本文我们来分析下高通Android7.1代码SystemUI的启动流程。ZygoteInit中handleSystemServerProcess函数的最后一步,会调用SystemServer的静态函数main方法。我们来看下那段有关启动SystemUI的代码:
frameworks\base\services\java\com\android\server\SystemServer.java
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
...
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
...
}
}
static final void startSystemUi(Context context) {
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);
}
可以看到当ActivityManagerService启动成功准备好后,就调用startSystemUI方法启动SystemUIService服务。此过程会创建com.android.systemui进程。具体的创建过程请参考博客:https://www.jianshu.com/p/327f583f970b
frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIService.java
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
直接调用SystemUIApplication的startServicesIfNeeded()方法。
frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIApplication.java
/**
* The classes of the stuff to start.
*/
private final Class>[] SERVICES = new Class[] {
com.android.systemui.tuner.TunerService.class,
com.android.systemui.keyguard.KeyguardViewMediator.class,
com.android.systemui.recents.Recents.class,
com.android.systemui.volume.VolumeUI.class,
Divider.class,
com.android.systemui.statusbar.SystemBars.class,
com.android.systemui.usb.StorageNotification.class,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class,
com.android.systemui.keyboard.KeyboardUI.class,
com.android.systemui.tv.pip.PipUI.class,
com.android.systemui.shortcut.ShortcutKeyDispatcher.class,
com.android.systemui.VendorServices.class
};
private void startServicesIfNeeded(Class>[] services) {
...
final int N = services.length;
for (int i=0; i cl = services[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
try {
Object newService = SystemUIFactory.getInstance().createInstance(cl);
mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
} 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();
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
startServicesIfNeeded通过反射启动了一系列的服务。这里的服务不是Android的service,它们其实是一个普通的java文件,里面的start方法是用来进行一些初始化操作。我们来关注一下SystemBars的实现,通过它我们才创建了状态栏与导航栏。
public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {
...
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
mServiceMonitor.start(); // will call onNoService if no remote service is found
}
...
@Override
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
createStatusBarFromConfig(); // fallback to using an in-process implementation
}
SystemBars调用ServiceMonitor的start后,ServiceMonitor又会通过消息机制回调SystemBars的onNoService方法,从而读取配置文件里面配置的具体内容,我的系统配置的是PhoneStatusBar:
PhoneStatusBar的start方法将对状态栏与导航栏进行创建,不过这是后话了。到这里SystemUI的启动我们就分析完了,欢迎大家留言指正。
参考博客:
https://blog.csdn.net/kebelzc24/article/details/53690121