内容简介:本文流程基于Android 9.0在SystemServer中有一个方法startSystemUi,当系统启动后,会执行到SystemServer的startSystemUi()方法,正是在这个方法中启动了SystemUIService。注意,这里的
本文流程基于Android 9.0
1.启动SystemUIService
在SystemServer中有一个方法startSystemUi,当系统启动后,会执行到SystemServer的startSystemUi()方法,正是在这个方法中启动了SystemUIService。
static final void startSystemUi(Context context, WindowManagerService windowManager) { Intent intent = new Intent(); // 指定了systemui的包名"com.android.systemui",指定了ServiceUIService的类名"com.android.systemui.SystemUIService" 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(); } 复制代码
2.在SystemUIService中启动SystemUI中的服务
SystemUIService.java
@Override public void onCreate() { super.onCreate(); //在oncreate方法中调用SystemUIApplication的startServicesIfNeeded来启动相关服务 ((SystemUIApplication) getApplication()).startServicesIfNeeded(); // code... } 复制代码
SystemUIApplication
/** * Makes sure that all the SystemUI services are running. If they are already running, this is a * no-op. This is needed to conditinally start all the services, as we only need to have it in * the main process. * <p>This method must only be called from the main thread.</p> */ public void startServicesIfNeeded() { String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents); startServicesIfNeeded(names); } 复制代码
注意,这里的 service
的 names
是从 config
文件中读取出来的,具体内容如下,其中就包含了 SystemBars
的路径:
<!-- SystemUI Services: The classes of the stuff to start. --> <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> 复制代码
具体的启动过程
private void startServicesIfNeeded(String[] services) { //这里就是方法名IfNeeded的原因,首先会判断boolean变量mServicesStarted是否为ture,为true,表示服务已经启动,就不需要执行后面的启动流程了 if (mServicesStarted) { return; } //定义一个用于启动SystemUI服务的数组,并且这些要启动的服务都是继承自SystemUI的 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"); } } Log.v(TAG, "Starting SystemUI services for user " + Process.myUserHandle().getIdentifier() + "."); 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]); //调用各个服务重写了的start()方法 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(); } } // code... //启动过一次后,就将mServicesStarted置为true,避免重复启动 mServicesStarted = true; } 复制代码
3.在SystemBars中启动statusbar
关于 SystemBars
类的注释是这样的,“根据产品配置,使用进程内实现,确保一个 status bar
服务能够一直运行”。
/** * Ensure a single status bar service implementation is running at all times, using the in-process * implementation according to the product config. */ 复制代码
那么status bar是怎样启动的呢?在SystemUIApplication中也是通过调用SystemBars的start()方法,在SystemBars中的start()方法中去启动statusbar。
@Override public void start() { if (DEBUG) Log.d(TAG, "start"); createStatusBarFromConfig(); } 复制代码
private void createStatusBarFromConfig() { if (DEBUG) Log.d(TAG, "createStatusBarFromConfig"); 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 { mStatusBar = (SystemUI) cls.newInstance(); } catch (Throwable t) { throw andLog("Error creating status bar component: " + clsName, t); } mStatusBar.mContext = mContext; mStatusBar.mComponents = mComponents; mStatusBar.start(); if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName()); } 复制代码
这里的clsName和之前服务的names一样,也是从config中读取的,具体如下,是StatusBar的类路径。
<!-- 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.StatusBar</string> 复制代码
于是乎,通过这样一种方式,就启动起来一个一直运行着的StatusBar服务了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 深入理解 RPC 交互流程
- 深入剖析Vue源码 - 实例挂载,编译流程
- 深入 Java 类加载全流程,值得你收藏
- RecyclerView 源码深入解析——绘制流程、缓存机制、动画等
- 步步深入MySQL:架构->查询执行流程->SQL解析顺序
- Spring源码分析(八)深入了解事务管理的流程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。