Android系统SystemUI启动过程

SystemUI主要完成的功能有:

(1)、Status bars

(2)、Navigation bars

(3)、Notification

(4)、Lockscreen

(5)、Quick settings

(6)、Overview(recent task switcher)

(7)VolumeUI

SystemUI的启动时在SystemServer.java中,

2384     private static void startSystemUi(Context context, WindowManagerService windowManager) {

2385         Intent intent = new Intent();

2386         intent.setComponent(new ComponentName("com.android.systemui",

2387                 "com.android.systemui.SystemUIService"));

2388         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);

2389         //Slog.d(TAG, "Starting service: " + intent);

2390         context.startServiceAsUser(intent, UserHandle.SYSTEM);

2391         windowManager.onSystemUiStarted();

2392     }

SystemUI启动第一个执行的函数是什么呢?由APP的启动过程可知(如果读者不了解这个过程可自行学习),Android系统会给应用创建独立的进程,并实例化Application对象,在SystemUI源码中的AndroidManifest.xml文件可以看到下图的配置:

255     <application

256         android:name=".SystemUIApplication"

257         android:persistent="true"

258         android:allowClearUserData="false"

259         android:allowBackup="false"

260         android:hardwareAccelerated="true"

261         android:label="@string/app_label"

262         android:icon="@drawable/icon"

263         android:process="com.android.systemui"

264         android:supportsRtl="true"

265         android:theme="@style/Theme.SystemUI"

266         android:defaultToDeviceProtectedStorage="true"

267         android:directBootAware="true"

268         tools:replace="android:appComponentFactory"

269         android:appComponentFactory=".SystemUIAppComponentFactory">

270         <!-- Keep theme in sync with SystemUIApplication.onCreate().

271              Setting the theme on the application does not affect views inflated by services.

272              The application theme is set again from onCreate to take effect for those views. -->

273

274         <!-- Broadcast receiver that gets the broadcast at boot time and starts

275              up everything else.

276              TODO: Should have an android:permission attribute

277              -->

278         <service android:name="SystemUIService"

279             android:exported="true"

280         />

通过上面的配图可知,因此在启动SystemUI应用时会创建SystemUIApplication对象并回调onCreate()方法

70     @Override

 71     public void onCreate() {

 72         super.onCreate();

 73         Log.v(TAG, "SystemUIApplication created.");

 74         // This line is used to setup Dagger's dependency injection and should be kept at the

 75         // top of this method.

 76         TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",

 77                 Trace.TRACE_TAG_APP);

 78         log.traceBegin("DependencyInjection");

 79         mContextAvailableCallback.onContextAvailable(this);

 80         log.traceEnd();

 81

 82         // Set the application theme that is inherited by all services. Note that setting the

 83         // application theme in the manifest does only work for activities. Keep this in sync with

 84         // the theme set there.

 85         setTheme(R.style.Theme_SystemUI);

 86

 87         if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {

 88             IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);

 89             bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);

 90             registerReceiver(new BroadcastReceiver() {

 91                 @Override

 92                 public void onReceive(Context context, Intent intent) {

 93                     if (mBootCompleted) return;

 94

 95                     if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");

 96                     unregisterReceiver(this);

97                     mBootCompleted = true;

 98                     if (mServicesStarted) {

 99                         final int N = mServices.length;

100                         for (int i = 0; i < N; i++) {

101                             mServices[i].onBootCompleted();

102                         }

103                     }

104

105

106                 }

107             }, bootCompletedFilter);

108

109             IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);

110             registerReceiver(new BroadcastReceiver() {

111                 @Override

112                 public void onReceive(Context context, Intent intent) {

113                     if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {

114                         if (!mBootCompleted) return;

115                         // Update names of SystemUi notification channels

116                         NotificationChannels.createAll(context);

117                     }

118                 }

119             }, localeChangedFilter);

120         } else {

121             // We don't need to startServices for sub-process that is doing some tasks.

122             // (screenshots, sweetsweetdesserts or tuner ..)

123             String processName = ActivityThread.currentProcessName();

124             ApplicationInfo info = getApplicationInfo();

125             if (processName != null && processName.startsWith(info.processName + ":")) {

126                 return;

127             }

128             // For a secondary user, boot-completed will never be called because it has already

129             // been broadcasted on startup for the primary SystemUI process.  Instead, for

130             // components which require the SystemUI component to be initialized per-user, we

131             // start those components now for the current non-system user.

132             startSecondaryUserServicesIfNeeded();

133         }

134     }

SystemUIApplication的onCreate执行完之后,这个时候就到了SystemUIService里的onCreate

//SystemUIService

35 public class SystemUIService extends Service {

 36

 37     @Override

 38     public void onCreate() {

 39         super.onCreate();

 40         ((SystemUIApplication) getApplication()).startServicesIfNeeded();

 41

 42         // For debugging RescueParty

 43         if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {

 44             throw new RuntimeException();

 45         }

 46

 47         if (Build.IS_DEBUGGABLE) {

 48             // b/71353150 - looking for leaked binder proxies

 49             BinderInternal.nSetBinderProxyCountEnabled(true);

 50             BinderInternal.nSetBinderProxyCountWatermarks(1000,900);

 51             BinderInternal.setBinderProxyCountCallback(

 52                     new BinderInternal.BinderProxyLimitListener() {

 53                         @Override

 54                         public void onLimitReached(int uid) {

 55                             Slog.w(SystemUIApplication.TAG,

 56                                     "uid " + uid + " sent too many Binder proxies to uid "

 57                                     + Process.myUid());

 58                         }

 59                     }, Dependency.get(Dependency.MAIN_HANDLER));

 60         }

 61     }

我们可以看到,在这里第一行就是调用到SystemUIApplication的startServicesIfNeeded, 这个函数干了什么呢

//SystemUIApplication

136     /**

137      * Makes sure that all the SystemUI services are running. If they are already running, this is a

138      * no-op. This is needed to conditinally start all the services, as we only need to have it in

139      * the main process.

140      * <p>This method must only be called from the main thread.</p>

141      */

142

143     public void startServicesIfNeeded() {

144         String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);

145         startServicesIfNeeded(/* metricsPrefix= */ "StartServices", names);

146     }

其实这个函数的作用就是用来启动SystemUI子系统服务,前面讲到的VolumeUI、StatusBar等都有对应的service,这里可以看到names变量是从一个资源文件里获取的,我们找到这个service的定义部分.

//config.xml

282     <!-- SystemUI Services: The classes of the stuff to start. -->

283     <string-array name="config_systemUIServiceComponents" translatable="false">

284         <item>com.android.systemui.util.NotificationChannels</item>

285         <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>

286         <item>com.android.systemui.keyguard.KeyguardViewMediator</item>

287         <item>com.android.systemui.recents.Recents</item>

288         <item>com.android.systemui.volume.VolumeUI</item>

289         <item>com.android.systemui.stackdivider.Divider</item>

290         <item>com.android.systemui.SystemBars</item>

291         <item>com.android.systemui.usb.StorageNotification</item>

292         <item>com.android.systemui.power.PowerUI</item>

293         <item>com.android.systemui.media.RingtonePlayer</item>

294         <item>com.android.systemui.keyboard.KeyboardUI</item>

295         <item>com.android.systemui.pip.PipUI</item>

296         <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>

297         <item>@string/config_systemUIVendorServiceComponent</item>

298         <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>

299         <item>com.android.systemui.LatencyTester</item>

300         <item>com.android.systemui.globalactions.GlobalActionsComponent</item>

301         <item>com.android.systemui.ScreenDecorations</item>

302         <item>com.android.systemui.biometrics.BiometricDialogImpl</item>

303         <item>com.android.systemui.SliceBroadcastRelayHandler</item>

304         <item>com.android.systemui.SizeCompatModeActivityController</item>

305         <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>

306         <item>com.android.systemui.theme.ThemeOverlayController</item>

307     </string-array>

可以看到其实里面定义了很多service,对应不同的子功能。

184         final int N = services.length;

185         for (int i = 0; i < N; i++) {

186             String clsName = services[i];

187             if (DEBUG) Log.d(TAG, "loading: " + clsName);

188             log.traceBegin(metricsPrefix + clsName);

189             long ti = System.currentTimeMillis();

190             Class cls;

191             try {

192                 cls = Class.forName(clsName);

193                 Object o = cls.newInstance();

194                 if (o instanceof SystemUI.Injector) {

195                     o = ((SystemUI.Injector) o).apply(this);

196                 }

197                 mServices[i] = (SystemUI) o;

198             } catch(ClassNotFoundException ex){

199                 throw new RuntimeException(ex);

200             } catch (IllegalAccessException ex) {

201                 throw new RuntimeException(ex);

202             } catch (InstantiationException ex) {

203                 throw new RuntimeException(ex);

204             }

205

206             mServices[i].mContext = this;

207             mServices[i].mComponents = mComponents;

208             if (DEBUG) Log.d(TAG, "running: " + mServices[i]);

209             mServices[i].start();

210             log.traceEnd();

每个service的具体实现和功能将在下文中描述。在图6中可以看到,实例化每个对象是向上转型为SystemUI对象,config_systemUIServiceComponents的所有service统一继承了SystemUI类.

//SystemUI.java

29 public abstract class SystemUI implements SysUiServiceProvider {

 30     public Context mContext;

 31     public Map<Class<?>, Object> mComponents;

 32

 33     public abstract void start();

 34

 35     protected void onConfigurationChanged(Configuration newConfig) {

 36     }

 37

 38     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {

 39     }

 40

 41     protected void onBootCompleted() {

 42     }

44     @SuppressWarnings("unchecked")

 45     public <T> T getComponent(Class<T> interfaceType) {

 46         return (T) (mComponents != null ? mComponents.get(interfaceType) : null);

 47     }

 48

 49     public <T, C extends T> void putComponent(Class<T> interfaceType, C component) {

 50         if (mComponents != null) {

 51             mComponents.put(interfaceType, component);

 52         }

 53     }

 54

 55     public static void overrideNotificationAppName(Context context, Notification.Builder n,

 56             boolean system) {

 57         final Bundle extras = new Bundle();

 58         String appName = system

 59                 ? context.getString(com.android.internal.R.string.notification_app_name_system)

 60                 : context.getString(com.android.internal.R.string.notification_app_name_settings);

 61         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, appName);

 62

 63         n.addExtras(extras);

 64     }

 65

 66     public interface Injector extends Function<Context, SystemUI> {

 67     }

 68 }

SystemUI类提供start()、onConfigurationChanged()、dump()等重要方法,每个方法在各个service中实现不一样。

至此,SystemUI的启动基本完成,从上文可知,SystemUI是系统中非常核心的应用,在Android系统开机过程中Server进程直接发起SystemUI启动,SystemUI也是固化程序,在保证系统正常运行发挥了非常重要的作用。

上一篇:android-intent


下一篇:安卓开发