Android 8.1 中Systemui中的常见修改(八)SystemUI加载流程
SystemUI作为系统应用,在开机的时候就会开始加载启动,今天来学习一下它的启动流程。
SystemServer.java (frameworks\base\services\java\com\android\server)
1.最开始会调用SystemServer里面的StartOtherService方法,我们可以看到startSystemUi方法实际上是启动了一个SystemUIService的服务。
private void startOtherServices() { ........ try { startSystemUi(context, windowManagerF); } catch (Throwable e) { reportWtf("starting System UI", e); } ...... }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到这里还没有启动成功,因为startOtherService()方法都还没有执行完毕。所以暂时还不会发送ACTION_BOOT_COMPLETE广播,该广播是在AMS中的finishBooting()中发送的。(该广播在我们SystemUIService中有做监听,用来判断是否完成系统启动)。
2.现在我们来看一下SystemUIService的里面的onCreate方法,实际上又调用了SystemUIApplication里面的startServicesIfNeeded方法。
SystemUIService.java (frameworks\base\packages\systemui\src\com\android\systemui)
public void onCreate() { super.onCreate(); ((SystemUIApplication) getApplication()).startServicesIfNeeded(); // For debugging RescueParty if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) { throw new RuntimeException(); } }
3.这里面把SystemUIApplication的onCreate方法都贴上了,大致的操作就是判断是否加载完成。
SystemUIApplication.java (frameworks\base\packages\systemui\src\com\android\systemui)
这里面需要注意的是对于安卓系统来说,当一个应用启动,系统会保证其Application类是第一个被实例化的类,并且Application的onCreate方法,一定先于应用中所有的Activity,Service和BroadcastReceiver的创建。
@Override public void onCreate() { super.onCreate(); // Set the application theme that is inherited by all services. Note that setting the // application theme in the manifest does only work for activities. Keep this in sync with // the theme set there. setTheme(R.style.Theme_SystemUI); SystemUIFactory.createFromConfig(this); if (Process.myUserHandle().equals(UserHandle.SYSTEM)) { //注册ACTION_BOOT_COMPLATETED广播 IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (mBootCompleted) return; if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received"); unregisterReceiver(this); mBootCompleted = true; if (mServicesStarted) { final int N = mServices.length; for (int i = 0; i < N; i++) { mServices[i].onBootCompleted(); } } } }, filter); } else { // We don't need to startServices for sub-process that is doing some tasks. // (screenshots, sweetsweetdesserts or tuner ..) String processName = ActivityThread.currentProcessName(); ApplicationInfo info = getApplicationInfo(); if (processName != null && processName.startsWith(info.processName + ":")) { return; } // For a secondary user, boot-completed will never be called because it has already // been broadcasted on startup for the primary SystemUI process. Instead, for // components which require the SystemUI component to be initialized per-user, we // start those components now for the current non-system user. startServicesIfNeeded(SERVICES_PER_USER); } }
我们在接着看startServicesIfNeeded方法,这里面就是把对应的服务启动起来。这里的服务不是Android的service,它们其实是一个普通的java文件,里面的start方法是用来进行一些初始化操作
private void startServicesIfNeeded(Class<?>[] services) {...... final int N = services.length; for (int i = 0; i < N; i++) { mServices[i].start();//启动对应的服务 }...... mServicesStarted = true;}
需要启动的服务:
private final Class<?>[] SERVICES = new Class[] { Dependency.class, NotificationChannels.class, CommandQueue.CommandQueueStart.class, KeyguardViewMediator.class, Recents.class, VolumeUI.class, Divider.class, SystemBars.class, StorageNotification.class, PowerUI.class, RingtonePlayer.class, KeyboardUI.class, PipUI.class, ShortcutKeyDispatcher.class, VendorServices.class, GarbageMonitor.Service.class, LatencyTester.class, GlobalActionsComponent.class, RoundedCorners.class, };
4.我们以启动SystemBars为例子,可以看到会调用mStatusBar.start(),来启动StatusBar。
SystemBars.java (frameworks\base\packages\systemui\src\com\android\systemui)
@Override public void start() { if (DEBUG) Log.d(TAG, "start"); createStatusBarFromConfig(); } private void createStatusBarFromConfig() { if (DEBUG) Log.d(TAG, "createStatusBarFromConfig"); //com.android.systemui.statusbar.phone.StatusBar final String clsName = mContext.getString(R.string.config_statusBarComponent); if (clsName == null || clsName.length() == 0) { throw andLog("No status bar component configured", null); } Class<?> cls = null; try { cls = mContext.getClassLoader().loadClass(clsName); } catch (Throwable t) { throw andLog("Error loading status bar component: " + clsName, t); } try { //StatusBar继承自SystemUI,反射生成的为StatusBar类型对象,引用为SystemUI类型引用 mStatusBar = (SystemUI) cls.newInstance(); } catch (Throwable t) { throw andLog("Error creating status bar component: " + clsName, t); } mStatusBar.mContext = mContext; mStatusBar.mComponents = mComponents; //在这里调用的statusBar的start方法 mStatusBar.start(); if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName()); }
5.在这里面我们就不做过多的阐述了,通过调用StatusBar里面的start方法来加载Statusbar上面的资源。
StatusBar.java (frameworks\base\packages\systemui\src\com\android\systemui\statusbar\phone)
可以查看之前的文章继续看流程。
Android 8.1 中Systemui中的常见修改(六)NavigationBar加载流程
这里,要注意的是SystemBars和StatusBar类都是继承自SystemUI,前者用于在systemui进程启动时和SystemUIApplication进行交互,并且包含一个SystemUI属性,用来指向一个StatusBar对象,并start()该对象。总结一下SystemBars的作用
在SystemUIApplication中通过反射得到SystemBars实例
通过反射得到StatusBar实例
start StatusBar实例
下面是SystemUIService的执行log
更多相关文章
- Android SDK23以上(包括23)无法使用httpclient的处理方法
- android 属性android:visibility及 view的setVisibility方法值的
- Android中使用WebView, WebChromeClient和WebViewClient加载网页
- [Android] AsyncTask使用实例---加载网络图片
- Android中使用animation的方法
- Android禁止EditText自动弹出软键盘的方法及遇到问题
- Android 获取未读短信同时,一并获取该短信内容的方法