概述
本文流程基于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服务了。
最后
以上就是安静大侠为你收集整理的[深入SystemUI]-SystemUI_statusbar的启动流程1.启动SystemUIService2.在SystemUIService中启动SystemUI中的服务3.在SystemBars中启动statusbar的全部内容,希望文章能够帮你解决[深入SystemUI]-SystemUI_statusbar的启动流程1.启动SystemUIService2.在SystemUIService中启动SystemUI中的服务3.在SystemBars中启动statusbar所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复