android9 SystemUI启动流程

一.SystemUI概述

SystemUI 是一个系统应用,apk路径位于/system/priv-app
源码路径位于:/framework/base/packages/SystemUI
主要负责功能:

  • StatusBar:状态栏
  • NavigationBar:导航栏(返回、home、近期任务)
  • Notification Panel:通知栏以及快捷设置面板
  • 壁纸管理
  • 截图功能
  • Recents:近期任务(android9使用的是launcher3里面的近期任务,但是SystemUI9也保留了相关代码,可在systemUi中设置使用哪个)
  • 录制屏幕功能
  • 截图服务
  • VolumeBar:音量控制
  • Keyguard 锁屏界面
  • RingtonePlayer 铃声播放器界面
  • PipUI 画中画界面
  • RingtonePlayer 铃声播放器界面
    。。。。。

二.SystemUI 的启动

系统开机大致流程:
uboot引导os启动 > 加载kernel > init进程,fork出zygote进程 > zygote启动SystemServer;
SystemServer负责系统各种核心服务的启动以及初始化和加载一些应用。
com.android.server.SystemServer.java:
main方法:

/**
 * The main entry point from zygote.
 */
 public static void main(String[] args) {
    
    
        new SystemServer().run();
 }

run()方法:

private void run() {
    
    
   ...
 // Start services.
 try {
    
    
        traceBeginAndSlog("StartServices");
        startBootstrapServices();  //引导服务
        startCoreServices();    //核心服务
        startOtherServices();  //其他
        SystemServerInitThreadPool.shutdown();
  }
   ...
}

三个start方法从命名可用看出分别用于启动引导服务、核心服务和其他服务。startBootstrapServices():

 private void startBootstrapServices() {
    
    
        ...
  Installer installer = mSystemServiceManager.startService(Installer.class);
  mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
  mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
  mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
  mActivityManagerService.setInstaller(installer);
  mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);   
  mSystemServiceManager.startService(LightsService.class);
  mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
        ...
 }

可以看到AMS,PMS,LightsService等服务是在这里开启的。
SystemUI的启动位于startOtherServices():

private void startOtherServices() {
    
    
   ...
   traceBeginAndSlog("StartSystemUI");
   try {
    
    
      startSystemUi(context, windowManagerF);
   } catch (Throwable e) {
    
    
      reportWtf("starting System UI", e);
   }
   ...
}

这个方法代码非常多,只列出了关键的地方,接着看startSystemUi方法:

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();
}

创建Intent,通过组件名com.android.systemui.SystemUIService启动了SystemUIService服务。至此终于走到了SystemUI项目中。

三.SystemUI的加载

com.android.systemui.SystemUIService.java

public class SystemUIService extends Service {
    
    

    @Override
    public void onCreate() {
    
    
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
        ...
    }
}

SystemUIService继承了Service,onCreate调用了SystemUIApplication的startServicesIfNeeded方法:

public class SystemUIApplication extends Application...{
    
    
  public void startServicesIfNeeded() {
    
    
    String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
        startServicesIfNeeded(names);
    }
 }

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>

可以看到对应上1中提到的各个功能模块。接下来是真正的加载方法,
startServicesIfNeeded(String[] services)

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();
            } 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;
            if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
            mServices[i].start();
            log.traceEnd();

            // Warn if initialization of component takes too long
            ti = System.currentTimeMillis() - ti;
            if (ti > 1000) {
    
    
                Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
            }
            if (mBootCompleted) {
    
    
                mServices[i].onBootCompleted();
            }
        }
       ......
    }

首先新建了SystemUI数组(mServices),再遍历传入的services数组通过反射获取SystemUI对象赋值给mServices数组,最后通过mServices[i].start()加载各个模块。注意这里的mServices[i].start并不是常说的启动服务,以NotificationChannels为例:
NotificationChannels 继承了SystemUI :

 public abstract class SystemUI implements SysUiServiceProvider {
    
    
    public Context mContext;
    public Map<Class<?>, Object> mComponents;

    public abstract void start();
    ....
 }
public class NotificationChannels extends SystemUI{
    
    
  @Override
    public void start() {
    
    
        createAll(mContext);
    }
}

也就是说各个模块都继承了SystemUI,各自重写了start方法,mServices[i].start()调用了各自模块的start方法,完成加载。

猜你喜欢

转载自blog.csdn.net/weixin_40652755/article/details/122670778