Android核心程序之SystemUI - (一)开篇
UI是实现用户交互的重要途径之一,而Android中一个重要的UI元素就是SystemUI,本文分析基于Android 5.1,分析SystemUI的启动及运行过程。
SystemUI源代码所在路径为:
frameworks/base/packages/SystemUI
查看AndroidManifest.xml,整理软件实现思路。
包名为
com.android.systemui
package="com.android.systemui"
分配的userID为
android.uid.systemui
android:sharedUserId="android.uid.systemui"
标明此应用为系统核心App
coreApp="true"
接下来是一系列的权限声明,包括
Networking and telephony
,Physical hardware
,ActivityManager
,WindowManager
,DreamManager
,Alarm clocks
,Keyguard
,Recents
,Wifi Display
,Screen Capturing
等方面的权限。接下来看 <application></application>中的内容:
此应用不会轻易被kill,并且会自动启动
android:persistent="true"
用户数据不可清除
android:allowClearUserData="false"
启用硬件加速
android:hardwareAccelerated="true"
设置系统进程
android:process="com.android.systemui"
其他属性为常规属性,很多app都会有,在此不再赘述。
接下来是分析SystemUI的重点,看下都涉及到了哪些activity,service和receiver。
activity:
.usb.UsbStorageActivity
com.android.internal.app.ExternalMediaFormatActivity
.recent.RecentsActivity
.recents.RecentsActivity
.usb.UsbConfirmActivity
.usb.UsbPermissionActivity
.usb.UsbResolverActivity
.usb.UsbAccessoryUriActivity
.usb.UsbDebuggingActivity
.net.NetworkOverLimitActivity
.media.MediaProjectionPermissionActivity
.DessertCase
.egg.LLandActivity
.Somnambulator
.settings.BrightnessDialog
service:
SystemUIService
.screenshot.TakeScreenshotService
.LoadAverageService
.ImageWallpaper
.DessertCaseDream
.keyguard.KeyguardService
.doze.DozeService
receiver:
.BootReceiver
.qs.tiles.HotspotTile$APChangedReceiver
.recent.RecentsPreloadReceiver
.recents.RecentsUserEventProxyReceiver
众多activity中并没有LAUNCHER,也就是说SystemUI是没有启动界面的。
SystemUI的启动
既然SystemUI没有启动界面,也无需人为启动,那么SystemUI是怎么启动起来的呢?接下来就将对这个问题进行说明。
- 在service中有一个SystemUIService,这就是入口。那么这个SystemUIService又是怎么启动的呢?要找到答案,就要考虑到这是一个系统app,自然会在系统完成初始化以后启动,那么利用Source Insight在frameworks/base中看看有没有。
从结果来看,在SystemService貌似有什么线索。打开SystemService.java(frameworks/base/services/java/com/android/server/),以下代码就展现在眼前了。
static final void startSystemUi(Context context) {Intent intent = new Intent();intent.setComponent(new ComponentName("com.android.systemui","com.android.systemui.SystemUIService"));//Slog.d(TAG, "Starting service: " + intent);context.startServiceAsUser(intent, UserHandle.OWNER); }
在代码中可以看到SystemUIService被启动了起来,那么哪里调用了这个方法呢?在此类中继续查找,又发现如下代码:
mActivityManagerService.systemReady(new Runnable() {@Overridepublic void run() {Slog.i(TAG, "Making services ready");mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);try {mActivityManagerService.startObservingNativeCrashes();} catch (Throwable e) {reportWtf("observing native crashes", e);}Slog.i(TAG, "WebViewFactory preparation");WebViewFactory.prepareWebViewInSystemServer();try {startSystemUi(context);} catch (Throwable e) {reportWtf("starting System UI", e);}...} }
由代码可知,ActivityManagerService调用了
systemReady()
方法,也就是系统就绪就会调用run()
方法。那么会在何时执行到此处呢?再往上探索,发现上述代码位于startOtherServices()
方法中,那么还是那个问题,何时调用startOtherServices()
方法。再往上探索,发现startOtherServices()
位于一个run()
方法中private void run() {···// Start services.try {startBootstrapServices();startCoreServices();startOtherServices();} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;}··· }
再往上追一追,最终找到了这个类的开始:
public static void main(String[] args) {new SystemServer().run(); }
嗯,这是···,很熟悉嘛。
至于SystemService则是由Zygote启动的,在此就不多追溯了。
至此,SystemServer已经启动,那么在SystemServer里面又做了什么事情呢?SystemUIService的初始化
在SystemUIService中,主要代码就一个
onCreate()
方法,来看看他做了啥:@Override public void onCreate() {super.onCreate();((SystemUIApplication) getApplication()).startServicesIfNeeded(); }
转型为SystemUIApplication并且调用
startServicesIfNeeded()
方法。那么接下来去看看startServicesIfNeeded()
方法做了些什么。public void startServicesIfNeeded() {if (mServicesStarted) {return;}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.");final int N = SERVICES.length;for (int i=0; i<N; i++) {Class<?> cl = SERVICES[i];if (DEBUG) Log.d(TAG, "loading: " + cl);try {mServices[i] = (SystemUI)cl.newInstance();} 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; }
根据代码中涉及到的mServices,追溯其来源:
private final SystemUI[] mServices = new SystemUI[SERVICES.length];
再往上,得到SERVICES的由来:private final Class<?>[] SERVICES = new Class[] {com.android.systemui.keyguard.KeyguardViewMediator.class,com.android.systemui.recent.Recents.class,com.android.systemui.volume.VolumeUI.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 };
在这里定义了很多System Panel,这里叫做SERVICES,并非真正的services,运行在SystemUIService中的子服务。此时再来回头看
onCreate()
方法:@Override public void onCreate() {super.onCreate();// Set the application theme that is inherited by all services. Note that setting the// application theme in the manifest does only work for activities. Keep this in sync with// the theme set there.setTheme(R.style.systemui_theme);IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);registerReceiver(new BroadcastReceiver() {@Overridepublic 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();}}}}, filter); }
在onCreate()方法中,注册了广播接收器,用于接收开机完成的广播,并将开机完成的状态传递给每个SERVICE。
经过以上代码的追溯,可知:
mServices[i] = (SystemUI)cl.newInstance();
//实例化子服务,并将其存储于mService[i]中。
mServices[i].mContext = this;
//设置mService[i]的Context
mServices[i].mComponents = mComponents;
//设置mService[i]的Components
mServices[i].start();
//运行mService[i]
至此,SystemUIService的启动就已完成,伴随着SystemUIService的完成,SystemUI的核心service也就启动了,SystemUIService的使命也就完成了,接下来的事情就交由各个子服务去完成了。
以上属于个人体验心得总结,若有不足之处,还望不吝赐教,欢迎批评指正,共同进步
转载于:https://www.cnblogs.com/cj5785/p/9892979.html
Android核心程序之SystemUI - (一)开篇相关推荐
- Android源码学习------SystemUI(二)
SystemUI----AndroidManifest文件 AndroidManifest是Android应用程序中最重要的文件之一.它是Android程序的全局配置文件,是每个 android程序中 ...
- Android核心分析之二十二Android应用框架之Activity
3 Activity设计框架 3.1 外特性空间的Activity 我们先来看看,android应用开发人员接触的外特性空间中的Activity,对于AMS来讲,这个Activity就是客服端的 ...
- 《OpenGL ES 3.x游戏开发(上卷)》一1.5 Android应用程序运行的机制
本节书摘来异步社区<OpenGL ES 3.x游戏开发(上卷)>一书中的第1章,第1.5节,作者: 吴亚峰 责编: 张涛,更多章节内容可以访问云栖社区"异步社区"公众号 ...
- 《Qt on Android核心编程》夹
china-pub在售前,售中环节退房,折扣低! 有朋友想看看<Qt on Android核心编程>的文件夹,So-- 文件夹 <Qt on Android核心编程>文件夹,截 ...
- 利用FRIDA攻击Android应用程序(一)
前言 直到去年参加RadareCon大会时,我才开始接触动态代码插桩框架Frida.最初,我感觉这玩意还有点意思,后来发现这种感觉是不对的:应该是非常有意思.您还记得游戏中的上帝模式吗?面对本地应用程 ...
- Android应用程序的组成部分和Manifest文件(转)
Android应用程序由松散耦合的组件组成,并使用应用程序Manifest绑定到一起:应用程序Manifest描述了每一组件和它们之间的交互方式,还用于指定应用程序元数据.其硬件和平台要求.外部库以及 ...
- Android应用程序组件Content Provider简要介绍和学习计划
在Android系统中,Content Provider作为应用程序四大组件之一,它起到在应用程序之间共享数据的作用,同时,它还是标准的数据访问接口.前面的一系列文章已经分析过Android应用程序的 ...
- 【转】独家教程:用PHP编写Android应用程序
Google的开源Android移动操作系统正在席卷全球智能手机市场,和苹果不一样,它对那些想将应用程序提交到iPhone App Store的开发人员有着严格的指导方针和要求,Google的Andr ...
- Android中级教程之--------Android应用程序的生命周期(一定要理解,面试会问的哦!)
Android的应用程序的生命周期,我相信这在以后的Android面试一定是经常考的题目,所以大家一点要重视哦!下面我将图文双线程,希望对大家有一点帮助! 首先我们看一下Android应用程序的生命周 ...
最新文章
- 前端资源系列(2)-SublimeText快捷键大全
- 层模型--绝对定位、相对定位、固定定位
- 9个妙招增强家庭WIFI信号
- 《Javascript权威指南》学习笔记之十二:数组、多维数组和符合数组(哈希映射)...
- SpringCloud工作笔记048---RESTful API 中 HTTP 状态码的定义_以及把RESTFul版本号_放到http协议header中_以及RestFul设计时的两个误区
- 百度地图API的第一次接触
- [深度学习] 深度学习常见概念
- vue可以编辑发布多长的视频_vue视频的总时长是多少
- FPGA入门学习——流水灯
- C51软件精确延时(us级)
- Hive(二):with as用法
- C++面向对象-12-加号运算符重载
- “沉迷单车的追风少年”的2021年年末总结
- 跨越逐梦路上的荆棘(程序猿生存指南)
- 2019-01-21第六课
- clap与slap_(2xslap,slap,slap,clap,slap)Doinapos;theFACTSNowthatapos;s.ppt
- vue使用cesium
- php 采集网页 webfont,webfont中文云端字体服务推荐:有字库
- 红黑树详解(一)红黑树的介绍和操作
- 浅谈友情链接对网站的影响
热门文章
- 如何在Eclipse里显示BPMN格式的流程图
- 如何用WebIDE打开并运行CRM Fiori应用
- 一位全加器的结构描述vhdl_小学数学结构化学习的评价实践探索
- python工程技巧_重点来了!掌握这些Python技巧,将给你节省大量时间
- html5游戏指尖跟随,图片跟随手指滑动
- java轻功游戏,会轻功又可以飞的游戏(3d大型游戏)
- case zhen语句_switch case语句,switch case用法详解
- ios解锁动态图片_iOS 苹果开机启动的 滑动来解锁动画
- unsigned short占几个字节_ARM中,字、半字、字节分别是多少位?
- 计算机考研各个学校科目,计算机考研学校的前几个排名