天天看點

Android SystemUI分析

原創文章,轉載請注明出處:http://blog.csdn.net/ruils/article/details/17324397

SystemUI即Android系統的UI界面。手機廠商需要深度定制Android系統的UI界面就需要修改這裡面的東西,比如雙卡手機,就需要在狀态欄增加手機狀态圖示。

SystemUI包括:

StatusBar,  狀态欄,最上面那一排

NavigationBar, 導航欄,最下面那一排虛拟鍵,有Back鍵,Home鍵,Recents鍵(最近使用程式清單鍵)

Recent APP List,最近使用程式清單界面

Wallpaper, 桌面

USB相關界面

其他等。

SystemUI所在目錄為frameworks/base/packages/SystemUI,從Android4.0以後的版本,SystemUI編譯都會生成SystemUI.apk。

SystemUI在SystemServer中被啟動:

frameworks/base/services/java/com/android/server/SystemServer.java

startSystemUi方法:

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.startServiceAsUser(intent, UserHandle.OWNER);
     }

           

啟動SyseUIService

frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java

SystemUIService的Oncreate方法:

@Override
    public void onCreate() {
        // Tell the accessibility layer that this process will
        // run as the current user, i.e. run across users.
        AccessibilityManager.createAsSharedAcrossUsers(this);

        // Pick status bar or system bar.
        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
        try {
            SERVICES[0] = wm.hasSystemNavBar()
                    ? R.string.config_systemBarComponent
                    : R.string.config_statusBarComponent;
        } 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();
        }   
    }   

           

分别調用SERVICES裡的類的start方法:

final Object[] SERVICES = new Object[] {
            0, // system bar or status bar, filled in below.
            com.android.systemui.power.PowerUI.class,
            com.android.systemui.media.RingtonePlayer.class,
            com.android.systemui.settings.SettingsUI.class,
        };
           

這個0從SystemUIService的onCreate方法中可以看到,會被config_systemBarComponent或者config_statusBarComponent替換掉。

// Pick status bar or system bar.
        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
        try {
            SERVICES[0] = wm.hasSystemNavBar()
                    ? R.string.config_systemBarComponent
                    : R.string.config_statusBarComponent;
        } catch (RemoteException e) {
            Slog.w(TAG, "Failing checking whether status bar can hide", e);
        }

           

frameworks/base/packages/SystemUI/res/values/config.xml

<!-- Component to be used as the status bar service.  Must implement the IStatusBar
     interface.  This name is in the ComponentName flattened format (package/class)  -->
    <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>

    <!-- Component to be used as the system bar service.  Must implement the IStatusBar
     interface.  This name is in the ComponentName flattened format (package/class)  -->
    <string name="config_systemBarComponent" translatable="false">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
           

這裡一個是手機的StatusBar一個是平闆的StatusBar。

我們看手機的StatusBar,

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

PhoneStatusBar的start()方法:

@Override
    public void start() {
        mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                .getDefaultDisplay();

        mDreamManager = IDreamManager.Stub.asInterface(
                ServiceManager.checkService(DreamService.DREAM_SERVICE));

        super.start(); // calls createAndAddWindows()

        addNavigationBar();

        if (ENABLE_INTRUDERS) addIntruderView();

        // Lastly, call to the icon policy to install/update all the icons.
        mIconPolicy = new PhoneStatusBarPolicy(mContext);
    }
           

這裡主要做了三件事:

1.将StatusBar添加到WindowManager中

在super.start()方法中調用createAndAddWindows()方法,

@Override
    public void createAndAddWindows() {
        addStatusBarWindow();
    }

    private void addStatusBarWindow() {
        // Put up the view
        final int height = getStatusBarHeight();

        // Now that the status bar window encompasses the sliding panel and its
        // translucent backdrop, the entire thing is made TRANSLUCENT and is
        // hardware-accelerated.
        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.TRANSLUCENT);

        lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;

        lp.gravity = getStatusBarGravity();
        lp.setTitle("StatusBar");
        lp.packageName = mContext.getPackageName();

        makeStatusBarView();
        mWindowManager.addView(mStatusBarWindow, lp);
    }

           

2.将NavigationBar添加到WindowManager中

addNavigationBar()

// For small-screen devices (read: phones) that lack hardware navigation buttons
    private void addNavigationBar() {
        if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
        if (mNavigationBarView == null) return;

        prepareNavigationBarView();

        mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
    }
           

3.執行個體化PhoneStatusBarPolicy