android4.0系統可以運行於平板電腦和手機上面,這樣對於狀態欄來說,也是有不同風格的,從SystemUi的代碼分類我就可以看出來,google考慮了不同情況下狀態欄的顯示等,
在源代碼裏面有這麼兩個文件夾需要注意:
com.android.systemui.statusbar.phone 這個是針對手機而需要的status bar
com.android.systemui.statusbar.tablet 這個是針對平板電腦而需要的status bar(system bar)
首先狀態欄是如何啓動起來的呢?
我們都知道系統剛啓動,在SystemServer會加載系統的各種服務,狀態欄也不例外,就是在這個時候創建的,代碼如下:
路徑:androidx86/framework/base/services/java/com/android/server/SystemServer.java
SystemServer.java
ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
startSystemUi(contextF);
try {
if (batteryF != null) batteryF.systemReady();
} catch (Throwable e) {
reportWtf("making Battery Service ready", e);
}
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
Slog.d(TAG, "Starting service: " + intent);
context.startService(intent);
}
通過上面的代碼我就看到系統啓動了com.android.systemui.SystemUIService這個服務,在這個服務裏面就會啓動狀態欄,
但是這裏就會有個選擇,是啓動status bar呢 還是啓動 system bar呢,android是這麼決定的:
路徑:androidx86/framework/base/packages/SystemUI/SystemUI.java
public void onCreate() {
// Pick status bar or system bar.
IWindowManager wm = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
try {
SERVICES[0] = wm.canStatusBarHide() (1)
? R.string.config_statusBarComponent(2)
: R.string.config_systemBarComponent;(3)
} catch (RemoteException e) {
Slog.w(TAG, "Failing checking whether status bar can hide", e);
}
final int N = SERVICES.length;
mServices = new SystemUI[N];
for (int i=0; i<N; i++) {
Class cl = chooseClass(SERVICES[i]);
Slog.d(TAG, "loading: " + cl);
try {
mServices[i] = (SystemUI)cl.newInstance();
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
Slog.d(TAG, "running: " + mServices[i]);
mServices[i].start();
}
}
該start方法在androidx86/framework/base/packages/SystemUI/statusbar/StatusBar.java
在start方法裏面就會創建狀態欄那些界面對應的各種view,包括下拉狀態欄後的view等,把這些view都創建好以後,就把這個view加載windowmanager裏面就可以了,這樣狀態欄就可以顯示出來了,代碼如下:
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height,
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.OPAQUE);
// the status bar should be in an overlay if possible
final Display defaultDisplay
= ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
if (ActivityManager.isHighEndGfx(defaultDisplay)) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(sb, lp); //這裏的sb就是狀態欄view
因爲我們要屏蔽狀態欄,所以也就把這句話屏蔽了就可以了。
OK!!!問題解決!