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系统SystemUI启动过程相关推荐
- Android系统的启动过程
Android系统的启动过程可以简单地总结为以下几个流程: 加载BootLoader -> 初始化内核 -> 启动init进程 -> init进程fork出Zygote(孵化器)进程 ...
- Android内核开发:图解Android系统的启动过程
本文是<Android内核开发>系列的第六篇文章,前面的几篇文章介绍了Android内核开发相关的基础知识,包括:Android源码的下载.版本和分支介绍.编译和烧写等等,从本文起就要开始 ...
- Android 解锁屏启动过程
Android 解锁屏启动过程 一. 开机启动 在开机过程中无线模块初始化时获取SIM卡,状态.在初始化完成后调用vm.systemReady()函数通知进入相应的Lock Screen进行解锁. 1 ...
- Android系统进程Zygote启动过程的源代码分析
原文地址:http://blog.csdn.net/luoshengyang/article/details/6747696 Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口 ...
- 结合源码探讨Android系统的启动流程
结合源码探讨Android系统的启动流程 由于本人能力有限,所考虑或者疏忽错漏的地方或多或少应该存在.同时,Android从启动过程开始,实际上就涉及多个技术难点和多种通信机制的知识点. 基于上面两个 ...
- Android系统开机启动流程
第一步:启动linux 1.Bootloader 2.Kernel 第二步android系统启动:入口为init.rc(system\core\rootdir) 1./system/bin/servi ...
- Linux系统的启动过程
下面是整个Linux系统的启动过程: Linux Boot Step Start BIOS grub/lilo Kernel boot init rc.sysinit ...
- android服务的启动过程,Android Service的启动过程(上)
原标题:Android Service的启动过程(上) (点击上方公众号,可快速关注) 来源:伯乐在线专栏作者 - xuyinhuan 链接:http://android.jobbole.com/85 ...
- Android系统的启动流程简要分析
这是我结合网上的资料以及自己分析android4.4的源码整理的笔记,对整个安卓系统的流程启动进行了梳理,很多细节并未展开,只是简要的进行了介绍. 一.Android系统的架构介绍 Android的整 ...
最新文章
- 资料分享:推荐一本《李宏毅机器学习》开源电子书!
- 集成学习+ensemble learning
- 在VB.NET中应用SQLDMO
- Flutter Dart:用数字分组显示大数字
- 设置(TableViewController)通用框架
- 牛客 - Connie(AC自动机+dp/KMP+dp)
- 【转】[SharePoint 开发详解] 一个Feature中使用SPGridView的几个Tips
- 利用c#开发一个telnet unix服务器或者防火墙的小工具(转)
- [转]MVC+JQuery validate实现用户输入验证
- 服务器配置能连多少个小程序,每个服务器能配置多少小程序
- 【去除教育】去除打印教育戳记插件
- 链表---合并两个有序链表
- DOS专题之基本命令
- leetcode刷题_day14_(str,hashmap)_code3(最长非重子串)
- openoffic需要的jar包
- 网络拓扑绘制软件亿图图示安装以及使用攻略
- 【学术】英文写作中值得参考的语法、句式(二)
- 使用Bboss处理ES的dsl语句
- hmailserver搭建一个公网可收发的自用邮局
- 【基于STM32F103+AS608的智能打卡系统】