android4.0 SystemUi系统状态栏
android4.0系統可以運行于平板電腦和手機上面,這樣對于狀態欄來說,也是有不同風格的,從SystemUi的代碼分類我就可以看出來,google考慮了不同情況下狀態欄的顯示等,
在源代碼里面有這么兩個文件夾需要注意:
com.android.systemui.statusbar.phone? 這個是針對手機而需要的status bar
com.android.systemui.statusbar.tablet?? 這個是針對平板電腦而需要的staus bar(system bar)
?
首先狀態欄是如何啟動起來的呢?
我們都知道系統剛啟動,在SystemServer會加載系統的各種服務,狀態欄也不例外,就是在這個時候創建的,代碼如下:
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是這么決定的:
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();
??????? }
??? }
?
上面的(1) 出,會調用到phoneWIndowManager里面對應的那個函數,在那里面會根據配置文件,手機寬高等信息來判斷使用哪一種bar,代碼如下
public boolean canStatusBarHide() {
??????? return mStatusBarCanHide;
??? }
?if (width > height) {
??????????? shortSize = height;
??????????.........
??????? } else {
??????????? shortSize = width;
??????????.......
??????? }
??????? // Determine whether the status bar can hide based on the size
??????? // of the screen.? We assume sizes > 600dp are tablets where we
??????? // will use the system bar.
??????? int shortSizeDp = shortSize
??????????????? * DisplayMetrics.DENSITY_DEFAULT
??????????????? / DisplayMetrics.DENSITY_DEVICE;
??????? mStatusBarCanHide = shortSizeDp < 600;
??????? mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
??????????????? mStatusBarCanHide
??????????????? ? com.android.internal.R.dimen.status_bar_height
??????????????? : com.android.internal.R.dimen.system_bar_height);
?
這里假如手機寬(高) 小于600dp,就認為是手機了,這樣mStatusBarHide = true;
我們回到這里
SERVICES[0] = wm.canStatusBarHide()??
??????????????????? ? R.string.config_statusBarComponent;
??????????????????? : R.string.config_systemBarComponent;
這樣SERVICES[0]? = R.string.config_statusBarComponent (這個字符串就是 com.anroid.systemui.statusbar.phone)
實際上SERVERCES這個數組里面就兩個元素,一個是我們上面的那個com.anroid.systemui.statusbar.phone ,另外一個是PowerUI,這個暫且不管,這個主要是根據電量等信息彈出一些提示框,比如電量低,或者充電器有問題等框。
接下來會調用com.anroid.systemui.statusbar.phone的start方法,注意com.anroid.systemui.statusbar.phone這個類不是一個服務,就是一個普通的類,start方法也是它的一個普通的方法而已。
在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
?
這里需要注意的是 平時看到的狀態欄和下拉后的狀態欄是兩個東西,不要混到一起,而且這里也會創建兩個view,一個是普通的狀態欄view,另外一個下拉后的view,這兩個view都要加載WindosManager里面,添加的代碼基本一樣,但是最重要的是那個參數里面的type是不一樣的,一個是WindowManager.LayoutParams.TYPE_STATUS_BAR,而下拉的那個type是WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
總結
以上是生活随笔為你收集整理的android4.0 SystemUi系统状态栏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 4.0 Notifica
- 下一篇: Android4.0添加底层核心服务