系统服务:SystemServer.java
SystemServer.java 中 SystemServer 是 zygote 进程起来的启动的第一个服务
SystemServer 内部有main方法,创建自身,并运行run方法,在该方法中
创建SystemServiceManager,PackageManagerService,ActivityManagerService等对象,ActivityThread,设置BinderInternal 等,
在其startOtherServices 方法中mActivityManagerService.systemReady(第一个参数是Runnable),在该Runnable的run方法中调用startSystemUi方法 启动SystemUI服务(值得注意的是Runnable的run方法直接运行的话,会直接在当前线程运行,也就是startSystemUi会在主线程中运行)。
startSystemUi方法中,我们启动了 SystemUIService,而在SystemUIService的onCreate方法 中调用了SystemUIApplication的startServicesIfNeeded方法
((SystemUIApplication) getApplication()).startServicesIfNeeded();
startServicesIfNeeded通过反射的方式将前面的各个子服务类实例化,并执行这些对象中的start()方法,来启动这些服务。这样整个SystemUI就算启动了
SystemUIApplication内部监听了开机广播和语言更换广播 ,要等到系统启动并锁屏界面解锁后,在进入到桌面过程中,系统才会发送发送开机广播,所以接收该广播的处理逻辑会比较延后
后面内容很多借鉴了,人家写的更有深度,我这只算是流程,更多是为了个人水平提升
public static void main(String[] args) {
new SystemServer().run();
}
private void run(){
try{
//省略
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
//省略
}
private void startOtherServices() {
//ActivityManagerService mActivityManagerService
mActivityManagerService.systemReady(new Runnable(){
@Override
public void run(){
try{
//启动SystemUI服务
startSystemUi(context);
}catch(Thorwable e){
reportWtf("starting System UI", e);
}
}
});
}
static final void startSystemUi(Context context){
Intent intent = new Intent();
intent.setComponent(new CompenentName("com.android.systemui","com.android.systemui.SystemUIService");
context.startServiceAsUser(intent, UserHandle.OWNER);
}
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
/**
Starts the small tangle of critical services that are needed to get the system off the ground. These services have complex mutual dependencies which is why we initialize them all in one place here. Unless your service is also entwined in these dependencies, it should be initialized in one of the other functions.
启动一些关键服务,这些服务是开启系统所必需的。这些服务具有复杂的相互依赖关系,这就是为什么我们在这里将它们都初始化在一个地方除非您的服务也缠绕在这些依赖项中,否则应该在其他函数中初始化它。
*/
private void startBootstrapServices() {
traceBeginAndSlog("StartInstaller");
Installer installer = mSystemServiceManager.startService(Installer.class);
traceEnd();
...
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
...
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
...
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
...
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
...
}
SystemUIService 代码如下:
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
// For debugging RescueParty
if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
throw new RuntimeException();
}
if (Build.IS_DEBUGGABLE) {
// b/71353150 - looking for leaked binder proxies
BinderInternal.nSetBinderProxyCountEnabled(true);
BinderInternal.nSetBinderProxyCountWatermarks(1000,900);
BinderInternal.setBinderProxyCountCallback(
new BinderInternal.BinderProxyLimitListener() {
@Override
public void onLimitReached(int uid) {
Slog.w(SystemUIApplication.TAG,
"uid " + uid + " sent too many Binder proxies to uid "
+ Process.myUid());
}
}, Dependency.get(Dependency.MAIN_HANDLER));
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
if (args == null || args.length == 0) {
for (SystemUI ui: services) {
pw.println("dumping service: " + ui.getClass().getName());
ui.dump(fd, pw, args);
}
if (Build.IS_DEBUGGABLE) {
pw.println("dumping plugins:");
((PluginManagerImpl) Dependency.get(PluginManager.class)).dump(fd, pw, args);
}
} else {
String svc = args[0];
for (SystemUI ui: services) {
String name = ui.getClass().getName();
if (name.endsWith(svc)) {
ui.dump(fd, pw, args);
}
}
}
}
}
SystemUIApplication startServicesIfNeeded代码如下
/**
* 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.
* This method must only be called from the main thread.
*/
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
/**
* Ensures that all the Secondary user 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.
* This method must only be called from the main thread.
*
* 当前用户不是系统用户时的情况,即切换用户后的场景,该动作发生时系统是已经启动了的,不会再触发Intent.ACTION_BOOT_COMPLETED广播
*/
void startSecondaryUserServicesIfNeeded() {
String[] names =
getResources().getStringArray(R.array.config_systemUIServiceComponentsPerUser);
startServicesIfNeeded(names);
}
private void startServicesIfNeeded(String[] services) {
if (mServicesStarted) {
return;
}
mServices = new SystemUI[services.length];
...
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);
//通过反射的方式将前面的各个子服务类实例化,并执行这些对象中的start()方法,来启动这些服务。这样整个SystemUI就算启动了
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]);
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();
}
}
SystemUIApplication 在onCreate方法中设置了主题,
@Override
public void onCreate() {
super.onCreate();
//设置所有服务继承的应用程序主题注意,在清单中设置应用程序主题只对活动有效。保持这个与那里的主题集同步。
setTheme(R.style.Theme_SystemUI);
SystemUIFactory.createFromConfig(this);
if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
//监听了开机广播,在之后,迅速注销,当整个系统启动完成后,
//这里面的每个子服务都会执行onBootCompleted()方法,
//让各个子服务知道系统启动完成了,要做自己该做的事情了
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();
}
}
}
}, bootCompletedFilter);
IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
if (!mBootCompleted) return;
// Update names of SystemUi notification channels
NotificationChannels.createAll(context);
}
}
}, localeChangedFilter);
} 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
startSecondaryUserServicesIfNeeded();
}
}
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.Dependencyitem>
<item>com.android.systemui.util.NotificationChannelsitem>
<item>com.android.systemui.statusbar.CommandQueue$CommandQueueStartitem>
<item>com.android.systemui.keyguard.KeyguardViewMediatoritem>
<item>com.android.systemui.recents.Recentsitem>
<item>com.android.systemui.volume.VolumeUIitem>
<item>com.android.systemui.stackdivider.Divideritem>
<item>com.android.systemui.SystemBarsitem>
<item>com.android.systemui.usb.StorageNotificationitem>
<item>com.android.systemui.power.PowerUIitem>
<item>com.android.systemui.media.RingtonePlayeritem>
<item>com.android.systemui.keyboard.KeyboardUIitem>
<item>com.android.systemui.pip.PipUIitem>
<item>com.android.systemui.shortcut.ShortcutKeyDispatcheritem>
<item>@string/config_systemUIVendorServiceComponentitem>
<item>com.android.systemui.util.leak.GarbageMonitor$Serviceitem>
<item>com.android.systemui.LatencyTesteritem>
<item>com.android.systemui.globalactions.GlobalActionsComponentitem>
<item>com.android.systemui.ScreenDecorationsitem>
<item>com.android.systemui.biometrics.BiometricDialogImplitem>
<item>com.android.systemui.SliceBroadcastRelayHandleritem>
<item>com.android.systemui.SizeCompatModeActivityControlleritem>
<item>com.android.systemui.statusbar.notification.InstantAppNotifieritem>
<item>com.android.systemui.theme.ThemeOverlayControlleritem>
string-array>
SystemUI是一个基类,其中定义了4个抽象或空方法,作为模板指定了子类的行为模式。资源文件中定义的众多子服务类都是SystemUI的子类,既然都继承自SystemUI类,那么这些子类就有一些共同的行为模式,在某些阶段应该有什么表现,只是具体如何表现因不同子类而异。
public abstract class SystemUI implements SysUiServiceProvider {
......
public abstract void start();
protected void onConfigurationChanged(Configuration newConfig) {
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
}
protected void onBootCompleted() {
}
......
}
}
上面注释说的是 确保所有辅助用户SystemUI服务都在运行,如果它们已经在运行,这是一个no-op。这需要有条件地启动所有服务,因为我们只需要在主进程中使用它。此方法只能从主线程调用
这样通过SystemUIService的启动,SystemUI核心的services也启动了。SystemUI Services启动后,根据各Services的功能,SystemUI开始正常工作。