Android源码学习 ——SystemUI(三)

SystemUI的启动流程

SystemUI属于系统级别的UI,是Android系统的核心应用,在开机过程中就会启动,负责反馈系统以及应用的状态,并与用户保持大量的交互。本系列文章涉及到的代码来自AndroidP版本。
为什么说SystemUI是在开机过程中启动的呢?
Init 是所有Linux程序的起点,而Android的启动过程都由Zygote产生。init 是 zygote的父进程, 而system_server和其他所有的com.xxx结尾的应用程序都是从zygote fork 而来。前面的SystemServer的启动过程不在涉猎范围之内,在此不做赘述,有兴趣的朋友可以从这里了解。
我们直接从SystemServer是如何启动SystemUI开始。先来一张时序图,能比较清晰完整的了解SystemUI的启动流程。
Android源码学习 ——SystemUI(三)_第1张图片
在./frameworks/base/services/java/com/android/server/SystemServer.java文件中,有个main方法:

public static void main(String[] args) {
    new SystemServer().run();
}

main方法中启动了run(),在run中启动了一系列的服务,在SystemServer代码中,对系统的服务类别分为三类:BootstrapServices(包含ServiceManager,ActivityManagerService,PackageManagerService,DisplayManagerService,PowerManagerService, LightsService等),CoreServices(包含BatteryService,UsageStatsService,WebViewUpdateService等),OtherServices(包含ConnectivityService, NetworkManagementService, storageManager, WindowManagerService, AlarmManagerService, SystemUI等)

private void private void run() {
......
  try {
      traceBeginAndSlog("StartServices");
      startBootstrapServices();
      startCoreServices();
      startOtherServices();
      SystemServerInitThreadPool.shutdown();
  } catch (Throwable ex) {
      Slog.e("System", "******************************************");
      Slog.e("System", "************ Failure starting system services", ex);
      throw ex;
  } finally {
      traceEnd();
  }
......  
}
private void startOtherServices() {
......
    traceBeginAndSlog("StartSystemUI");
    try {
         startSystemUi(context, windowManagerF);
     } catch (Throwable e) {
          reportWtf("starting System UI", e);
     }
          traceEnd();
......
}
   
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();
}

通过startServiceAsUser启动SystemUIService,并调用其onCreate方法。

./frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
public class SystemUIService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
        ......}
  }

在onCreate方法中会调用SystemUIApplication中的startServicesIfNeeded方法,实际会调用startServicesIfNeeded(String),实例化SystemUI中的核心组件,并启动。

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];
        if (!mBootCompleted) {
            // check to see if maybe it was already completed long before we began
            // see ActivityManagerService.finishBooting()
            if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
                mBootCompleted = true;
                if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
            }
        }
        TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming", Trace.TRACE_TAG_APP);
        log.traceBegin("StartServices");
        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();
           ......
        mServicesStarted = true;
    }
./SystemUI/res/values/config.xml

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

startServicesIfNeeded方法遍历config_systemUIServiceComponents数组services[i],紧接着通过反射将其转化为具体类的对象,存在数组mServices[i]中 ,并调用start()方法依次启动对应组件,启动完成后会回调 onBootCompleted( ) 方法。mService[i] 里的值不同时,调用的每个组件中的 start() 方法也不相同。config_systemUIServiceComponents数组中包含了SystemUI中需要启动的组件,这些组件都是SystemUI的子类实现。在之后的文章中会逐一对各组件的启动和运行流程进行学习分析。

你可能感兴趣的:(Android,SystemUI)