内容简介:本文流程基于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服务了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Uberland
Alex Rosenblat / University of California Press / 2018-11-19 / GBP 21.00
Silicon Valley technology is transforming the way we work, and Uber is leading the charge. An American startup that promised to deliver entrepreneurship for the masses through its technology, Uber ins......一起来看看 《Uberland》 这本书的介绍吧!