《SytemUI》啓動流程

簡介


Android系統中有3個非常重要的應用,分別是SystemUI,launcher,Setting

  1. Setting:顯示需要用戶知道的設置項目,以前讓用戶配置自己系統的設置
  2. launcher:顯示所有的應用,展示應用入口
  3. SystemUI:顯示重要的信息,比如信號,電量,供用戶操作的導航欄

Android 的 SystemUI 其實就是 Android 的系統界面,它包括了界面上方的狀態欄 status bar,下方的導航欄Navigation Bar,鎖屏界面 Keyguard ,電源界面 PowerUI,近期任務界面 Recent Task 等等。對於用戶而言,SystemUI 的改動是最能直觀感受到的。因此,每個 Android 版本在 SystemUI 上都有比較大的改動。而對開發者而言,理解 Android SystemUI 對優化Android系統界面,改善用戶體驗十分重要。

SystemUI的啓動


Android系統在啓動系統服務器SystemService的時候,會啓動各個服務器,而在啓動這個服務器之後會啓動launcher和SystemUI

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

public final class SystemServer {
    private void run() {
        startBootstrapServices();
        startCoreServices();
        startOtherServices(); 
    }
    
    private void startOtherServices() {
        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        mActivityManagerService.systemReady(() -> {
            startSystemUi(context, windowManagerF);
        }

    }
}

可以看出在系統在啓動所有服務器之後,監聽mActivityManagerService狀態,如果“systemReady”後,啓動SytemUI,AMS的systemReady先啓動SystemUI之後啓動launcher,我們這裏只關注SystemUI


    static final void startSystemUi(Context context, WindowManagerService windowManager) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }

可以看見啓動的是SystemUI的服務,然後調用 windowManager.onSystemUiStarted();

windowManager.onSystemUiStarted();執行了下面的流程

  1. windowManagerSerivce#onSystemUiStarted
  2. PhoneWindoiwManager#onSystemUiStarted
  3. KeyguardServiceDelegate#KeyguardServiceDelegate
    public void bindService(Context context) {
        context.bindServiceAsUser(intent, mKeyguardConnection,//注1
                Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)
    }

注1:這裏的intent是SystemUI的keygaurdServUC兒,通過獲取SystemUI的keyguard,控制SystemU的鎖屏。

SystemService啓動SystemUIService


SystemUIService類十分簡短,下面基本就是他全部的代碼,

public class SystemUIService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

他只是調用SystemUIApplication的startServicesIfNeeded方法

public class SystemUIApplication extends Application implements SysUiServiceProvider {

    public void startServicesIfNeeded() {
        String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
        startServicesIfNeeded(names);
    }
    
    private void startServicesIfNeeded(String[] services) {
    if (mServicesStarted) {
        return;
    }
    mServices = new SystemUI[services.length];

    final int N = services.length;
    for (int i = 0; i < N; i++) {
        String clsName = services[i];
        if (DEBUG) Log.d(TAG, "loading: " + clsName);
        log.traceBegin("StartServices" + clsName);
        long ti = System.currentTimeMillis();
           Class cls;
        try {
            cls = Class.forName(clsName);
            mServices[i] = (SystemUI) cls.newInstance();//new it
        } catch(ClassNotFoundException ex){
                throw new RuntimeException(ex);
        } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
        } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
        }

        mServices[i].mContext = this;
        mServices[i].mComponents = mComponents;
    }

}

可以看到他通過反射實例化config_systemUIServiceComponents數組對應的“service”,然後調用start方法。
config_systemUIServiceComponents有哪些呢?

    <string-array name="config_systemUIServiceComponents" translatable="false">
        <item>com.android.systemui.Dependency</item>
        <item>com.android.systemui.util.NotificationChannels</item>
        <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
        <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
        <item>com.android.systemui.recents.Recents</item>
        <item>com.android.systemui.volume.VolumeUI</item>
        <item>com.android.systemui.stackdivider.Divider</item>
        <item>com.android.systemui.SystemBars</item>
        <item>com.android.systemui.usb.StorageNotification</item>
        <item>com.android.systemui.power.PowerUI</item>
        <item>com.android.systemui.media.RingtonePlayer</item>
        <item>com.android.systemui.keyboard.KeyboardUI</item>
        <item>com.android.systemui.pip.PipUI</item>
        <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
        <item>@string/config_systemUIVendorServiceComponent</item>
        <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
        <item>com.android.systemui.LatencyTester</item>
        <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
        <item>com.android.systemui.ScreenDecorations</item>
        <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
        <item>com.android.systemui.SliceBroadcastRelayHandler</item>
    </string-array>

這些類繼承SystemUI,SystemUI類又是幹什麼的呢?
這個應用主要界面都是顯示在Android屏幕部分區域,這些界面沒有通過Activity控制,SystemUI類具有管理的功能,如在屏幕旋轉會調用onConfigurationChanged方法,各個界面就可以做出相應的顯示,調用onstar啓動相應的模塊。

啓動SystemBars


各個模塊比較多,已SystemBars爲例進行分析。在startServicesIfNeeded方法中會實例化這個模塊,然後調用其start方法。

SystemBars類(去除不重要的代碼,以及log)

public class SystemBars extends SystemUI {
    @Override
    public void start() {
        createStatusBarFromConfig();
    }

    private void createStatusBarFromConfig() {
        //
        final String clsName =com.android.systemui.statusbar.phone.StatusBar mContext.getString(R.string.config_statusBarComponent);
        Class<?> cls = null;
        cls = mContext.getClassLoader().loadClass(clsName);
        mStatusBar = (SystemUI) cls.newInstance();
        mStatusBar.mContext = mContext;
        mStatusBar.mComponents = mComponents;
        mStatusBar.start();
    }
}

SystemBars實例化了R.string.config_statusBarComponent對應的com.android.systemui.statusbar.phone.StatusBar這個類,並調用其start方法。

public class StatusBar extends SystemUI{
    @Override
    public void start() {
        createAndAddWindows();
    }
    public void createAndAddWindows() {
        addStatusBarWindow();
    }
    private void addStatusBarWindow() {
        makeStatusBarView();
        mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
        mRemoteInputManager.setUpWithPresenter(this, mEntryManager, this,
                new RemoteInputController.Delegate() {
                    public void setRemoteInputActive(NotificationData.Entry entry,
                            boolean remoteInputActive) {
                        mHeadsUpManager.setRemoteInputActive(entry, remoteInputActive);
                        entry.row.notifyHeightChanged(true /* needsAnimation */);
                        updateFooter();
                    }
                    public void lockScrollTo(NotificationData.Entry entry) {
                        mStackScroller.lockScrollTo(entry.row);
                    }
                    public void requestDisallowLongPressAndDismiss() {
                        mStackScroller.requestDisallowLongPress();
                        mStackScroller.requestDisallowDismiss();
                    }
                });
        mRemoteInputManager.getController().addCallback(mStatusBarWindowManager);
        mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
    }
    
    protected void inflateStatusBarWindow(Context context) {
        mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
                R.layout.super_status_bar, null);
    }

}

最後通過inflateStatusBarWindow獲取view,然後mStatusBarWindowManager添加這個view,並顯示出來。

SystemBars加載各個視圖


SystemBars加載基本全部SystemUI的界面顯示,由於佈局太多,查找起來十分麻煩,我從其他人那裏copy過來,鏈接:++https://www.jianshu.com/p/2e0f403e5299++

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章