完整的启动过程:
Android启动流程学习框架:
Android的systemServer zygote ServiceManager
ServiceManager最先启动,Zygote再启动,最后启动systemServer。启动顺序决定了进程的依赖性.
启动Zygote目的,就是为了启动systemServer进程
systemserver中的service都需要连接sm.所以sm先启动
serviceManager只有一个功能就是提供binder通讯服务,Zygote也是一个功能创建java进程.
app的启动:app通过binder告诉SystemServer,然后SystemServer告诉Zygote,最后Zygote启动app.
app调用service总的来说就是通过serviceManager找到对应服务的binder proxy
serviceManager中注册了很多service,每一个service对应一个binder代理---这样就是一个线程一个binder了.
zynoteinit 调用startSystemServer创建system_server进程,ss调用handlesystemserverprocess完成自己的使命
图解: Android系统启动过程由上图从下往上的一个过程是由Boot Loader引导开机,然后依次进入 -> Kernel -> Native -> Framework -> App。
notes: 这部分内部不主要。只要把上面的几个图看懂. 知道init启动zygote. zygote创建systemserver,然后等待其他创建进程request. systemserver进程启动60个services.
Loader层:激活Kernel。
启动电源以及系统启动:当电源按下时引导芯片代码将固化在ROM中的引程序Bootloader加载到RAM,然后执行。
引导程序Bootloader:它是Android操作系统开始运行前的 一个小程序,负责把系统OS拉起来并运行。
linux内核启动:内核启动时,设置缓存、被保护存储器、计划列表,加载驱动等,为最终调用系统内核准备好环境。
Kernel层:Android内核空间,到这里才刚刚开始进入Android系统。
Bootloader启动Kernel的swapper进程(pid=0),它是内核首个进程,用于初始化进程管理、内存管理、加载各种驱动。更重要的是启动如下两个重要进程:
init进程(pid=1):用户进程的鼻祖
threadd进程(pid=2):内核进程的鼻祖
这层真正大主管是threadd进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。
Native层:进入用户空间。
这层init进程(pid=1)是大主管。它负责孵化各种系统级服务、守护进程等。最重要的是孵化出Zygote进程:Java进程的鼻祖。
Media Server进程:负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。
Framework层:在Native之上,也是用户空间,主要给app层提供api以及系统服务。
这层大主管是 Zygote进程。它负责注册Zygote Socket服务端套接字,加载虚拟机,preloadClasses和preloadResouces。
System Server进程:负责启动和管理整个Java framework,包含AMS、WMS、PMS等服务。
App层:应用程序。
所有的App进程都是由Zygote进程fork生成的。
Init篇
一、Init简介
init进程是Android系统中用户空间的第一个进程(pid=1),它是用户进程的鼻祖,负责孵化各种属性服务、守护进程也包括非常重要的Zygote。init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init。本文将基于Android7.0源码来分析Init进程。
二、Init分析
当内核完成系统设置,它首先在系统文件中寻找”init”文件,最后会调用 /system/core/init/Init.cpp 的 main() 方法。它是init的入口函数。那么来看init.cpp main方法:
int main(int argc, char** argv) {
…
//创建文件并挂载
if (is_first_stage) {
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
mount("sysfs", "/sys", "sysfs", 0, NULL);
}
...
//初始化属性相关资源
property_init();
...
//启动属性服务
start_property_service();
...
Parser& parser = Parser::GetInstance();
...
//解析init.rc配置文件
parser.ParseConfig("/init.rc");
...
return 0;
}
主要关注两点:初始化和启动属性服务、解析init.rc配置文件并启动zygote进程。
2.1 属性服务
Android提供的属性服务类似于Windows平台上注册表管理器的机制,内容采用键值对的形式来记录用户、软件的一些使用信息。即使系统或者软件重启,它还是能够根据之前在注册表中的记录,进行相应的初始化工作。应用程序可以通过这个属性机制,查询或者设置相应的属性。我们可以使用getprop命令来查看当前系统中都有哪些属性。
//初始化属性相关资源
property_init();
...
//启动属性服务
start_property_service();
此处初始化并启动了属性服务,代码细节不追究,了解下结论。
2.2 解析init.rc配置文件并启动zygote进程
2.2.1 了解Android Init Language
init.rc是一个配置文件,内部由Android初始化语言(Android Init Language)编写的脚本。先来学习下AIL:
它主要包含四种类型语句:Action、Commands、Services、Options
Action(动作): 通过trigger,即以 on开头的语句,决定何时执行相应的service。
on property:<key>=<value>: 当属性值满足条件时触发;...
启动顺序:on early-init -> init -> late-init -> boot
Service(服务):是一个程序,他在初始化时启动,并在退出时重启(可选),由init进程启动,一般运行于另外一个init的子进程,所以启动service前需要判断对应的可执行文件是否存在。init生成的子进程,定义在rc文件,其中每一个service,在启动时会通过fork方式生成子进程。
例: service servicemanager(服务名 ) /system/bin/servicemanager ( 路径)
Command(命令): 要执行的命令
常用的命令:
class_start <service_class_name>: 启动属于同一个class的所有服务;
start <service_name>: 启动指定的服务,若已启动则跳过;
stop <service_name>: 停止正在运行的服务
...
Option(选项):Options是Services的可选项,与service配合使用
Action与Option配合使用:
on <trigger>
<command>
<command>
举例:
on boot
ifup lo
hostname localhost
domainname localdomain
class_start default
Service与Command配合使用:
service <name> <pathname> [ <argument> ]*
<option>
<option>
举例:
service healthd /sbin/healthd
class core
critical
seclabel u:r:healthd:s0
group root system wakelock
另外还有个import,它的作用是导入其他rc文件。
//init.rc 中
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
2.2.2 zygote进程的启动
回到解析init.rc配置文件:
parser.ParseConfig("/init.rc”);
这个parser即init_parse.cpp,通过它对init.rc进行解析。在Android 7.0中对init.rc文件进行了拆分,每个服务一个rc文件。我们要分析的zygote服务的启动脚本则在system/core/rootdir/init.zygoteXX.rc中定义,这里拿64位处理器为例,init.zygote64.rc的代码如下所示
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
通过init_parser.cpp完成整个service解析工作,此处就不详细展开讲解析过程,该过程主要是创建一个名”zygote”的service结构体,一个socketinfo结构体(用于socket通信),以及一个包含4个onrestart的action结构体。
Zygote服务会随着main class的启动而启动,退出后会由init重启zygote,即使多次重启也不会进入recovery模式。zygote所对应的可执行文件是/system/bin/app_process64,通过调用pid =fork()创建子进程,通过execve(svc->args[0], (char)svc->args, (char) ENV),进入App_main.cpp的main()函数。故zygote是通过fork和execv共同创建的。
流程如下:
app_main.cpp的main()方法中,最终通过Androidrumtime来启动zygote进程。
2.3 服务重启
init进程会启动很多native的service,这些service如果不是oneshot的,当service出现异常挂掉后,init需要将其重新启动起来:
具体操作不详细跟了,了解一下结论:
所有的Service里面只有servicemanager ,zygote ,surfaceflinger这3个服务有onrestart关键字来触发其他service启动过程。
//zygote可触发media、netd以及子进程(包括system_server进程)重启
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
//servicemanager可触发healthd、zygote、media、surfaceflinger、drm重启
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
//surfaceflinger可触发zygote重启
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
所以surfaceflinger,servicemanager、system_server以及zygote自身进程被杀都会触发Zygote重启
总结init的主要工作:
1.创建一些文件夹并挂载设备。
2.初始化和启动属性服务。
3.通过解析init.rc 和 其他对应rc文件,启动对应的系统级进程。其中包括后面要讲的zygote。
Zygote篇
Zygote是由init进程通过解析init.zygote.rc文件而创建的,zygote所对应的可执行程序app_process,所对应的源文件是App_main.cpp,进程名为zygote。
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
Zygote进程能够重启的地方:
servicemanager进程被杀; (onresart)
surfaceflinger进程被杀; (onresart)
Zygote进程自己被杀; (oneshot=false)
system_server进程被杀; (waitpid)
从App_main()开始,Zygote启动过程的函数调用类大致流程如下:
在Android系统中,Zygote是java进程的鼻祖。它在启动时会创建虚拟机,并通过fork(复制进程)的形式来创建应用程序进程和SystemServer进程。
作用: startVM()方法创建虚拟机,再调用startReg()注册JNI函数,启动system_server,runSelectLoop等待创建新进程请求
一、Zygote启动流程
从上篇文章得知init启动Zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start来启动zygote进程的,我们就从app_main.cpp的main函数开始分析。
1.1 AndroidRuntime.cpp
AppRuntime声明在app_main.cpp中,它继承AndroidRuntime,也就是我们调用start其实是调用AndroidRuntime的start函数。
frameworks/base/core/jni/AndroidRuntime.cpp start( )方法中主要工作:
调用startVm函数来创建JavaVm(DVM),并通过调用startReg函数用来为DVM注册JNI
startVm(&mJavaVM, &env, zygote)
startReg(env)
找到ZygoteInit的main函数,并通过JNI调用,自此Zygote便进入了Java框架层。
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V”);
env->CallStaticVoidMethod(startClass, startMeth, strArray);
1.2 ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java main( )方法中主要工作:
注册Zygote用的Socket,当Zygote进程将SystemServer进程启动后,就会在这个服务端的Socket上来等待ActivityManagerService请求Zygote进程来创建新的应用程序进程。
registerZygoteSocket(socketName);
预加载的资源、类、虚拟机实例等。
preload();
启动SystemServer进程,该进程承载着framework的核心服务。
startSystemServer(abiList, socketName);
循环等待并处理AMS发送来的创建新应用进程请求。如果收到创建应用程序的请求,则调用ZygoteConnection的runOnce函数来创建一个新的应用程序进程。
runSelectLoop(abiList);
整体流程时序图如下:
Zygote进程启动总结:
解析init.zygote.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法,实际调用AndroidRuntime.start(), 通过startVM()方法创建虚拟机,再调用startReg()注册JNI函数;
通过JNI方式调用ZygoteInit.main(),第一次进入Java世界;
registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求;
preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率;
通过startSystemServer(),fork得力帮手system_server进程,也是上层framework系统服务的运行载体。
zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
同时会因为surfaceflinger,servicemanager,system_server进程被杀而被动触发Zygote重启
对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,从名字可以看出分别对应32位和64位,但是确实是都创建了。
mido:/ # ps | grep zygote
root 714 1 2176388 47548 poll_sched 7faf1bd660 S zygote64
root 715 1 1613320 35496 poll_sched 00f292e3f4 S zygote
二、copy-on-write fork了解一下
以Zygote进程fork应用程序进程为例:
Zygote进程地址空间中包含有预加载资源、预加载类、虚拟机实例等。当Zygote fork一个应用程序进程时,父子进程先是共享相同物理地址资源,但是仅仅只能读不能写,如果此时应用进程开始写操作,那么会从Zygote原物理地址中复制内容到一块新的物理地址上,供应用程序进程使用。这样子进程可以高效而完整地继承父进程内存地址中的数据。
SystemServer篇
从上篇的Zygote学习中,了解到Zygote进程最后启动了SyetemServer进程,那么这篇文章就来分析下SystemServer。
notes: 启动所有services
一、SystemServer启动流程
这个过程在zygote进程中,主要包括这么几个内容:
1.1 Zygote fork SystemServer
1.2 当system_server进程创建失败时,将会重启zygote进程:
1.3 Zygote通过信号处理函数SigChldHandler监听所有子进程的存亡
二、SystemServer启动后的工作
关键流程说明:
ZygoteInit.startSystemServer()
fork 子进程 system_ server,进入 system_ server 进程。
ZygoteInit.handleSystemServerProcess()
设置当前进程名为“system_ server”,创建 PathClassLoader 类加载器。
RuntimeInit.zygoteInit()
重定向 log 输出,通用的初始化(设置默认异常捕捉方法,时区等),初始化 Zygote -> nativeZygoteInit()
app_main::onZygoteInit()
proc->startThreadPool(); 启动Binder线程池,这样就可以与其他进程进行通信。
ZygoteInit.main()
开启 DDMS 功能,preload() 加载资源,预加载OpenGL,调用 SystemServer.main() 方法
SystemServer.main()
先初始化 SystemServer 对象,再调用对象的 run() 方法。
SystemServer.run()
createSystemContext
startBootstrapServices();
startCoreServices();
startOtherServices();
Looper.loop();
SystemServer.run
private void run() {
//当系统时间比1970年更早,就设置当前系统时间为1970年
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//变更虚拟机的库文件,对于Android 6.0默认采用的是libart.so
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
if (SamplingProfilerIntegration.isEnabled()) {
...
}
//清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间
VMRuntime.getRuntime().clearGrowthLimit();
//设置内存的可能有效使用率为0.8
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// 针对部分设备依赖于运行时就产生指纹信息,因此需要在开机完成前已经定义
Build.ensureFingerprintProperty();
//访问环境变量前,需要明确地指定用户
Environment.setUserRequired(true);
//确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority)
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
// 主线程looper就在当前线程运行
Looper.prepareMainLooper();
//加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
System.loadLibrary("android_servers");
//检测上次关机过程是否失败,该方法可能不会返回[见小节1.2.1]
performPendingShutdown();
//初始化系统上下文 【见小节1.3】
createSystemContext();
//创建系统服务管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//启动各种系统服务
try {
startBootstrapServices(); // 启动引导服务【见小节1.4】
startCoreServices(); // 启动核心服务【见小节1.5】
startOtherServices(); // 启动其他服务【见小节1.6】
} catch (Throwable ex) {
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
//用于debug版本,将log事件不断循环地输出到dropbox(用于分析)
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
//一直循环执行
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
startBootstrapServices
private void startBootstrapServices() {
//阻塞等待与installd建立socket通道
Installer installer = mSystemServiceManager.startService(Installer.class);
//启动服务ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
//启动服务PowerManagerService
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
//初始化power management
mActivityManagerService.initPowerManagement();
//启动服务LightsService
mSystemServiceManager.startService(LightsService.class);
//启动服务DisplayManagerService
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//Phase100: 在初始化package manager之前,需要默认的显示.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
//当设备正在加密时,仅运行核心
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
mOnlyCore = true;
}
//启动服务PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
//启动服务UserManagerService,新建目录/data/user/
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
AttributeCache.init(mSystemContext);
//设置AMS
mActivityManagerService.setSystemProcess();
//启动传感器服务
startSensorService();
}
该方法所创建的服务:ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服务.
startCoreServices
private void startCoreServices() {
//启动服务BatteryService,用于统计电池电量,需要LightService.
mSystemServiceManager.startService(BatteryService.class);
//启动服务UsageStatsService,用于统计应用使用情况
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
//启动服务WebViewUpdateService
mSystemServiceManager.startService(WebViewUpdateService.class);
}
启动服务BatteryService,UsageStatsService,WebViewUpdateService。
startOtherServices
该方法比较长,有近千行代码,逻辑很简单,主要是启动一系列的服务,这里就不具体列举源码了,在第四节直接对其中的服务进行一个简单分类。
private void startOtherServices() {
...
SystemConfig.getInstance();
mContentResolver = context.getContentResolver(); // resolver
...
mActivityManagerService.installSystemProviders(); //provider
mSystemServiceManager.startService(AlarmManagerService.class); // alarm
// watchdog
watchdog.init(context, mActivityManagerService);
inputManager = new InputManagerService(context); // input
wm = WindowManagerService.main(...); // window
inputManager.start(); //启动input
mDisplayManagerService.windowManagerAndInputReady();
...
mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount
mPackageManagerService.performBootDexOpt(); // dexopt操作
ActivityManagerNative.getDefault().showBootMessage(...); //显示启动界面
...
statusBar = new StatusBarManagerService(context, wm); //statusBar
//dropbox
ServiceManager.addService(Context.DROPBOX_SERVICE,
new DropBoxManagerService(context, new File("/data/system/dropbox")));
mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler
lockSettings.systemReady(); //lockSettings
//phase480 和phase500
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
...
// 准备好window, power, package, display服务
wm.systemReady();
mPowerManagerService.systemReady(...);
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(...);
//重头戏[见小节2.1]
mActivityManagerService.systemReady(new Runnable() {
public void run() {
...
}
});
}
三、系统服务
startBootstrapServices:引导服务
服务 | 作用 |
Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |
ActivityManagerService | 负责四大组件的启动、切换、调度。 |
PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
LightsService | 管理和显示背光LED |
DisplayManagerService | 用来管理所有显示设备 |
UserManagerService | 多用户模式管理 |
SensorService | 为系统提供各种感应器服务 |
PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操作 |
startCoreServices:核心服务(3个)
服务 | 作用 |
BatteryService | 管理电池相关的服务 |
UsageStatsService | 收集用户使用每一个APP的频率、使用时常 |
WebViewUpdateService | WebView更新服务 |
startOtherServices:其他服务(90多种)
服务 | 作用 |
CameraService | 摄像头相关服务 |
AlarmManagerService | 全局定时器管理服务 |
InputManagerService | 管理输入事件 |
WindowManagerService | 窗口管理服务 |
VrManagerService | VR模式管理服务 |
BluetoothService | 蓝牙管理服务 |
NotificationManagerService | 通知管理服务 |
DeviceStorageMonitorService | 存储相关管理服务 |
LocationManagerService | 定位管理服务 |
AudioService | 音频相关管理服务 |
… | …. |
四、SystemServiceManager分析
从名字就很明显知道SystemServiceManager是系统服务管理类,简单了解两个方法:
4.1 startService函数
很简单,就是通过反射创建服务对象,并调用其onStart( )方法启动。
创建ActivityManagerService.Lifecycle对象;
调用Lifecycle.onStart()方法。
4.2 startBootPhase函数
Systemserver会将设备启动分成几个阶段,每个阶段service通过继承SytemService实现的onBootPhase方法来做一些对应的操作,相当于一个回调。
ActivityManagerService篇
ActivityManagerService(简称AMS)是Android系统的核心服务之一。它的主要作用是管理系统中所有应用进程以及应用进程中的四大组件。
notes: 建立和SS进程联系;启动子services; 消息循环线程,不断地接收其他进程发给AMS的消息,启动home activity.
一、AMS的启动过程
接上篇SystemServer run( )方法,AMS的启动过程主要包含在如下两个方法中:
private void run() {
...
startBootstrapServices();//创建并启动AMS服务,同时执行AMS启动后的一些初始化工作
startOtherServices();// 进入下个阶段的一些准备工作
...
}
接下来按这两个方法来分析
一、startBootstrapServices( )
1.1 创建并启动AMS服务
private void startBootstrapServices() {
...
//启动AMS服务
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
//设置AMS的系统服务管理器
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
//设置AMS的APP安装器
mActivityManagerService.setInstaller(installer);
//初始化AMS相关的PMS
mActivityManagerService.initPowerManagement();
...
//想ServiceManager注册一系列服务,并创建system_server对应的ProcessRecord并初始化
mActivityManagerService.setSystemProcess();
}
我们知道SystemServiceManager.startService是通过反射创建服务对象,并启动。但是这里传进去的是AMS的Lifecycle。Lifecycle是AMS中的一个静态内部类,它继承SystemService,由它来代理处理AMS的的创建与启动。
AMS.Lifecycle
[-> ActivityManagerService.java]
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start();
}
public ActivityManagerService getService() {
return mService;
}
}
这样SystemServiceManager间接通过调用Lifecycle创建并启动了AMS服务。
AMS是运行在system_server进程中的Framework服务,经过SystemServiceManager创建的服务会统一保存在队列管理。
1.2、AMS初始化工作
1.2.1 ActivityManagerService的构造方法:
public ActivityManagerService(Context systemContext) {
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();//默认为FACTORY_TEST_OFF
mSystemThread = ActivityThread.currentActivityThread();
//创建名为"ActivityManager"的前台线程,并获取mHandler
mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
//通过UiThread类,创建名为"android.ui"的线程
mUiHandler = new UiHandler();
//前台广播接收器,在运行超过10s将放弃执行
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
//后台广播接收器,在运行超过60s将放弃执行
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
//创建ActiveServices,其中非低内存手机mMaxStartingBackground为8
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
//创建目录/data/system
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
//创建服务BatteryStatsService
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
...
//创建进程统计服务,信息保存在目录/data/system/procstats,
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
// User 0是第一个,也是唯一的一个开机过程中运行的用户
mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
mUserLru.add(UserHandle.USER_OWNER);
updateStartedUserArrayLocked();
...
//CPU使用情况的追踪器执行初始化
mProcessCpuTracker.init();
...
mRecentTasks = new RecentTasks(this);
// 创建ActivityStackSupervisor对象
mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
//创建名为"CpuTracker"的线程
mProcessCpuThread = new Thread("CpuTracker") {
public void run() {
while (true) {
synchronized(this) {
final long now = SystemClock.uptimeMillis();
long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
if (nextWriteDelay < nextCpuDelay) {
nextCpuDelay = nextWriteDelay;
}
if (nextCpuDelay > 0) {
mProcessCpuMutexFree.set(true);
this.wait(nextCpuDelay);
}
}
updateCpuStatsNow(); //更新CPU状态
}
}
};
...
}
该过程共创建了3个线程,分别为”ActivityManager”,”android.ui”,”CpuTracker”。
首先,创建了一个名为“ActivityManager”的消息循环线程,不断地接收其他进程发给AMS的消息;并把该消息循环线程与MainHandler绑定,这样,由MainHandler完成消息的具体处理。
然后,创建了一些服务,并在/data/system目录下创建该服务需要的文件或文件夹,具体如下:
服务 | 服务说明 | 文件 | 文件说明 |
BatteryStatsService | 电池状态管理 | /data/system/batterystats.bin | 记录包括电压在内的各种电池信息 |
ProcessStatsService | 进程状态管理 | /data/system/procstats | 记录各个进程的状态信息 |
AppOpsService | 应用操作权限管理 | /data/system/appops.xml | 存储各个app的权限设置和操作信息 |
ActivityManagerService.start
private void start() {
Process.removeAllProcessGroups(); //移除所有的进程组
mProcessCpuThread.start(); //启动CpuTracker线程
mBatteryStatsService.publish(mContext); //启动电池统计服务
mAppOpsService.publish(mContext);
//创建LocalService,并添加到LocalServices
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
1.2.2 ActivityManagerService.setSystemProcess
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
//【见小节2.3.1】
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
//创建ProcessRecord对象
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true; //设置为persistent进程
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
updateLruProcessLocked(app, false, null);//维护进程lru
updateOomAdjLocked(); //更新adj
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("", e);
}
}
首先,向SystemServiceManager中添加了若干个服务:
服务 | 服务说明 |
activity | AMS服务本身 |
procstats | 进程状态管理 |
meminfo | 获取内存信息 |
gfxinfo | 监控分析GPU profiling信息 |
dbinfo | 数据库相关服务 |
cpuinfo | 获取cpu相关信息 |
permission | 权限控制相关服务 |
然后,调用PMS的getApplicationInfo接口,获取名为”android”的应用程序信息。包名为”android”的apk即/system/framework/framework-res.apk,里面保存着系统GUI美化的相关文件,包括图标,弹出对话框的样式,动作特效,界面布局等。调用installSystemApplicationInfo加载framework-res.apk文件。
接着,调用newProcessRecordLocked新建一个ProcessRecord 对象app。ProcessRecord用来描述一个进程的所有信息,包括该进程的所有activity和service等。在这里就是system_server(AMS就是在system_server进程中运行的)。创建后,对app的一些成员变量进行初始化,包括设置为常驻内存运行;设置system_server的pid等。
最后,调用mProcessNames.put()将创建的ProcessRecord 对象app加入到ProcessMap< ProcessRecord >类型的成员变量mProcessNames中。这里,app.processName=“system”。
这样,AMS就得到了system_server的ProcessRecord,以后AMS也可以管理system_server了。
setSystemProcess()过程向servicemanager注册了如下这个binder服务
服务名 | 类名 | 功能 |
activity | ActivityManagerService | AMS |
procstats | ProcessStatsService | 进程统计 |
meminfo | MemBinder | 内存 |
gfxinfo | GraphicsBinder | 图像信息 |
dbinfo | DbBinder | 数据库 |
cpuinfo | CpuBinder | CPU |
permission | PermissionController | 权限 |
processinfo | ProcessInfoService | 进程服务 |
usagestats | UsageStatsService | 应用的使用情况 |
想要查看这些服务的信息,可通过dumpsys <服务名>命令。比如查看CPU信息命令dumpsys cpuinfo。
二、startOtherServices( )
2.1 systemServer触发AMS的准备工作:
private void startOtherServices() {
...
//安装系统Provider 【见小节2.4.1】
mActivityManagerService.installSystemProviders();
...
//phase480 && 500
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
...
//【见小节3.1】
mActivityManagerService.systemReady(new Runnable() {
public void run() {
//phase550
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
...
//phase600
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
...
}
}
}
AMS.installSystemProviders
public final void installSystemProviders() {
List<ProviderInfo> providers;
synchronized (this) {
ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
providers = generateApplicationProvidersLocked(app);
if (providers != null) {
for (int i=providers.size()-1; i>=0; i--) {
ProviderInfo pi = (ProviderInfo)providers.get(i);
//移除非系统的provider
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
providers.remove(i);
}
}
}
}
if (providers != null) {
//安装所有的系统provider
mSystemThread.installSystemProviders(providers);
}
// 创建核心Settings Observer,用于监控Settings的改变。
mCoreSettingsObserver = new CoreSettingsObserver(this);
}
2.2 mActivityManagerService.systemReady()
主要分三个阶段来讲:
public void systemReady(final Runnable goingCallback) {
before goingCallback; // 见小节[3.1]
goingCallback.run(); // 见小节[3.2]
after goingCallback; // 见小节[3.3]
}
2.2.1 before goingCallback
ynchronized(this) {
if (mSystemReady) { //首次为flase,则不进入该分支
if (goingCallback != null) {
goingCallback.run();
}
return;
}
mRecentTasks.clear();
//恢复最近任务栏的task
mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
mTaskPersister.startPersisting();
if (!mDidUpdate) {
if (mWaitingUpdate) {
return;
}
final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
//处于升级过程【见小节3.1.1】
mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
public void run() {
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
showBootMessage(mContext.getText(
R.string.android_upgrading_complete),
false);
writeLastDonePreBootReceivers(doneReceivers);
systemReady(goingCallback);
}
}, doneReceivers, UserHandle.USER_OWNER);
if (mWaitingUpdate) {
return;
}
mDidUpdate = true;
}
mAppOpsService.systemReady();
mSystemReady = true;
}
ArrayList<ProcessRecord> procsToKill = null;
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
//非persistent进程,加入procsToKill
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
synchronized(this) {
if (procsToKill != null) {
//杀掉procsToKill中的进程, 杀掉进程且不允许重启
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
removeProcessLocked(proc, true, false, "system update done");
}
}
mProcessesReady = true; //process处于ready状态
}
Slog.i(TAG, "System now ready");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
SystemClock.uptimeMillis());
该阶段的主要功能:
向PRE_BOOT_COMPLETED的接收者发送广播;
杀掉procsToKill中的进程, 杀掉进程且不允许重启;
此时,系统和进程都处于ready状态;
2.2.2 goingCallback.run()
此处的goingCallback,便是在startOtherServices()过程中传递进来的参数
private void startOtherServices() {
...
mActivityManagerService.systemReady(new Runnable() {
public void run() {
//phase550
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
mActivityManagerService.startObservingNativeCrashes();
//启动WebView
WebViewFactory.prepareWebViewInSystemServer();
//启动系统UI【见小节3.2.1】
startSystemUi(context);
// 执行一系列服务的systemReady方法
networkScoreF.systemReady();
networkManagementF.systemReady();
networkStatsF.systemReady();
networkPolicyF.systemReady();
connectivityF.systemReady();
audioServiceF.systemReady();
Watchdog.getInstance().start(); //Watchdog开始工作
//phase600
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
//执行一系列服务的systemRunning方法
wallpaper.systemRunning();
inputMethodManager.systemRunning(statusBarF);
location.systemRunning();
countryDetector.systemRunning();
networkTimeUpdater.systemRunning();
commonTimeMgmtService.systemRunning();
textServiceManagerService.systemRunning();
assetAtlasService.systemRunning();
inputManager.systemRunning();
telephonyRegistry.systemRunning();
mediaRouter.systemRunning();
mmsService.systemRunning();
}
});
}
这部分是回调到systemServer startOtherServices中完成的:
此阶段主要工作总结:
startBootPhase:550(PHASE_ACTIVITY_MANAGER_READY),回调相应onBootPhase()方法;
启动WebView进程;
启动systemui服务;
startBootPhase:600(PHASE_THIRD_PARTY_APPS_CAN_START),回调相应onBootPhase()方法;
执行一系列服务的systemReady方法;
执行一系列服务的systemRunning方法;
startSystemUi
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
context.startServiceAsUser(intent, UserHandle.OWNER);
}
启动服务”com.android.systemui/.SystemUIService”
2.2.3 after goingCallback.run()
//启动【见小节3.3.1】
mSystemServiceManager.startUser(mCurrentUserId);
synchronized (this) {
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
//通过pms获取所有的persistent进程
List apps = AppGlobals.getPackageManager().
getPersistentApplications(STOCK_PM_FLAGS);
if (apps != null) {
int N = apps.size();
int i;
for (i=0; i<N; i++) {
ApplicationInfo info = (ApplicationInfo)apps.get(i);
if (info != null && !info.packageName.equals("android")) {
//启动persistent进程
addAppLocked(info, false, null);
}
}
}
}
mBooting = true;
// 启动桌面Activity 【见小节3.3.2】
startHomeActivityLocked(mCurrentUserId, "systemReady");
...
long ident = Binder.clearCallingIdentity();
try {
//system发送广播USER_STARTED
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
broadcastIntentLocked(...);
//system发送广播USER_STARTING
intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
broadcastIntentLocked(...);
} finally {
Binder.restoreCallingIdentity(ident);
}
mStackSupervisor.resumeTopActivitiesLocked();
sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
}
此阶段主要工作总结:
回调所有SystemService的onStartUser()方法;
启动persistent进程;
启动home Activity;
发送广播USER_STARTED和USER_STARTING;
发送广播USER_SWITCHED;
最后画了个简单时序图总结下AMS启动流程:
AMS.systemReady()的大致过程如下:
public final class ActivityManagerService{
public void systemReady(final Runnable goingCallback) {
...//更新操作
mSystemReady = true; //系统处于ready状态
removeProcessLocked(proc, true, false, "system update done");//杀掉所有非persistent进程
mProcessesReady = true; //进程处于ready状态
goingCallback.run(); //这里有可能启动进程
addAppLocked(info, false, null); //启动所有的persistent进程
mBooting = true; //正在启动中
startHomeActivityLocked(mCurrentUserId, "systemReady"); //启动桌面
mStackSupervisor.resumeTopActivitiesLocked(); //恢复栈顶的Activity
}
}
再说一说mProcessesReady:
startProcessLocked()过程对于非persistent进程必须等待mProcessesReady = true才会真正创建进程,否则进程放入mProcessesOnHold队列。 当然以下情况不会判断mProcessesReady:
addAppLocked()启动persistent进程; //但此时已经mProcessesReady;
finishBooting()启动on-hold进程; //但此时已经mProcessesReady;
cleanUpApplicationRecordLock() //启动需要restart进程,前提是进程已创建;
attachApplicationLocked() //绑定Bind死亡通告失败,前台同样是进程要已创建。
还有一个特殊情况,可以创建进程:processNextBroadcast()过程对于flag为FLAG_RECEIVER_BOOT_UPGRADE的广播拉进程 ,只在小节3.1.1的升级过程会出现。
由此可见,mProcessesReady在没有ready前,则基本没有应用进程。
Launcher篇
经过之前Android系统一系列启动流程,终于到了用户可视化操作界面了,即:Home桌面了,它是一个应用程序,叫Launcher。它主要展示一个个应用的快捷图标,并且通过点击图标来启动相应的应用程序。那么这篇文章就来解读下它。
notes:基本没有什么有用的. Launcher是用工作区的形式来显示系统安装的应用程序的快捷图标,每一个工作区都是来描述一个抽象桌面的.它由n个屏幕组成,每个屏幕又分n个单元格,每个单元格用来显示一个应用程序的快捷图标
一、Launcher的启动流程
接上篇AMS最后讲到的startHomeActivityLocked
public void systemReady(final Runnable goingCallback){
...
startHomeActivityLocked(currentUserId, "systemReady");
...
}
boolean startHomeActivityLocked(int userId, String reason) {
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, [aInfo.name](http://aInfo.name)));
// Don't do this if the home app is currently being instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}} }
首先是调用getHomeIntent()方法,看一下getHomeIntent是如何实现构造Intent对象的:
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
启动Launcher的Intent对象中添加了Intent.CATEGORY_HOME常量,这个其实是一个launcher的标志,一般系统的启动页面Activity都会在androidManifest.xml中配置这个标志。
看下Launcher的AndroidManifest.xml:
//packages/apps/Launcher3/AndroidManifest.xml
<activity
android:name="com.android.launcher3.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:theme="@style/Theme"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="nosensor"
android:configChanges="keyboard|keyboardHidden|navigation"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
最后通过如下代码启动home的Activity:
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
具体流程牵扯到Activity的启动流程,之后会有专门章节来总结,这里就简单列举下之后的执行路径:
ActivityStarter.startHomeActivityLocked
|
ActivityStarter.startActivityLocked 验证intent、Class、Permission等 ,保存将要启动的Activity的Record
|
ActivityStarter.doPendingActivityLaunchesLocked
|
ActivityStarter.startActivityUnchecked 检查将要启动的Activity的launchMode和启动Flag ,根据launcheMode和Flag配置task
|
ActivityStack.startActivityLocked
|
ActvityStack.startActivityLocked 任务栈历史栈配置
|
ActivityStack.resumeTopActivityInnerLocked() 查找要进入暂停的Activity
|
ActivityStack.startPausingLocked() 通过ipc告诉要暂停的Activity进入暂停
|
ActivityThread.handlePauseActivity() 1正式让之前的Activity暂停 2 告诉AMS已经暂停完成
|
ActivityManagerService.activityPaused()
|
ActivityStack.activityPausedLocked()
|
ActivityStackSuperVisor.resumeTopActivitiesLocked()
|
ActivityStack.resumeTopActivityLocked() 验证是否该启动的Activity所在进程和app是否存在,若存在,直接启动,否则,准备创建该进程
|
ActivityStackSuperVisor.startSpecificActivityLocked() 该进程不存在,创建进程
|
ActivityManagerService.startProcessLocked()
|
ActivityManagerService.startProcessLocked() 通过Process.start(“android.app.ActivityThread”)启动进程
|
ActivityThread.main()
|
ActivityThread.attach() 创建了 Instrumentation()
|
IActivityManager.attachApplication()
|
ActivityStackSuperVisor.attachApplicationLocked() 准备启动应用,先查找MainActivity
|
ActivityStackSuperVisor.realStartActivityLocked() IPC通知ActivityThread
|
ActivityThread.scheduleLaunchActivity() H 发消息 sendMessage(H.LAUNCH_ACTIVITY, r);
|
ActivityThread.handleLaunchActivity()
|
ActivityThread.performLaunchActivity()
|
Instrumentation.newActivity() 创建activity
|
activity.attach( )
|
Instrumentation.callActivityOnCreate 最终执行Activity onCreate
二、launcher中应用图标显示流程
经过前面的启动分析,我们终于进入到Launcher的主Activity了
public class Launcher extends Activity{
private LauncherModel mModel;
onCreate(Bundle savedInstanceState){
...
LauncherAppState app =LauncherAppState.getInstance(); //LauncherAppState创建单例对象
…
mModel = app.setLauncher(this);
setContentView(R.layout.launcher); //设置布局
…
//load显示数据
// We only load the page synchronously if the user rotates (or triggers a
// configuration change) while launcher is in the foreground
mModel.startLoader(mWorkspace.getRestorePage());
}...}}
看样子核心功能都在LauncherModel里:
先看看 mModel = app.setLauncher(this);
LauncherModel setLauncher(Launcher launcher) {
getLauncherProvider().setLauncherProviderChangeListener(launcher);
mModel.initialize(launcher);
mAccessibilityDelegate = ((launcher != null) && Utilities.ATLEAST_LOLLIPOP) ?
new LauncherAccessibilityDelegate(launcher) : null;
return mModel;
}
主要做了个初始化操作:
//LauncherModel
public void initialize(Callbacks callbacks) {
unbindItemInfosAndClearQueuedBindRunnables();
mCallbacks = new WeakReference<Callbacks>(callbacks);
}
在initialize函数中会将Callbacks,也就是传入的Launcher 封装成一个弱引用对象。
因此我们得知mCallbacks变量指的是封装成弱引用对象的Launcher,这个mCallbacks后文会用到它.
回到onCreate 看看后面LauncherModel.startLoader方法:
...
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");//创建了具有消息循环的线程HandlerThread对象
static {
sWorkerThread.start();
}
@Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper());//创建了Handler,并且传入HandlerThread的Looper。
...
public void startLoader(int synchronousBindPage, int loadFlags) {
InstallShortcutReceiver.enableInstallQueue();
stopLoaderLocked();
mLoaderTask=new LoaderTask(mApp.getContext(),loadFlags);//创建LoaderTask
if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
&& mAllAppsLoaded && mWorkspaceLoaded && !mIsLoaderTaskRunning) {
mLoaderTask.runBindSynchronousPage(synchronousBindPage);
} else {
sWorkerThread.setPriority(Thread.NORM_PRIORITY);
sWorker.post(mLoaderTask);//将LoaderTask作为消息发送给HandlerThread
} }
LoaderTask类实现了Runnable接口,当LoaderTask所描述的消息被处理时则会调用它的run函数,代码如下所示:
//LauncherModel
private class LoaderTask implements Runnable {
...
final List<LauncherActivityInfoCompat> apps = mLauncherApps.getActivityList(null, user);
...
mHandler.post(new Runnable() {
public void run() {
mIsLoaderTaskRunning = true;
keep_running: {
loadAndBindWorkspace();//调用loadAndBindWorkspace函数用来加载工作区信息
if (mStopped) {
break keep_running;
}
waitForIdle();
loadAndBindAllApps();//用来加载系统已经安装的应用程序信息
}
mContext = null;
mIsLoaderTaskRunning = false;
mHasLoaderCompletedOnce = true;
}}...}
mLauncherApps.getActivityList执行的是
//LauncherAppsmService.getLauncherActivities(packageName, user);
而mService 是:
ILauncherApps.Stub.asInterface(
ServiceManager.getService(Context.LAUNCHER_APPS_SERVICE)));
也就是最终由LauncherAppService执行getLauncherActivities:
@Override
public ParceledListSlice<ResolveInfo> getLauncherActivities(String packageName, UserHandle user) throws RemoteException {
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
mainIntent.setPackage(packageName);
long ident = Binder.clearCallingIdentity();
try {
List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
user.getIdentifier());
return new ParceledListSlice<>(apps);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
最终由PMS 执行queryIntentActivitiesAsUser 去获取要展示的APP信息.(这部分之后总结PMS再细说)
Launcher是用工作区的形式来显示系统安装的应用程序的快捷图标,每一个工作区都是来描述一个抽象桌面的.它由n个屏幕组成,每个屏幕又分n个单元格,每个单元格用来显示一个应用程序的快捷图标。这里loadAndBindWorkspace不分析,直接看加载数据相关的loadAndBindAllApps, loadAndBindAllApps又会调用loadAllApps:
//LauncherModel
private void loadAllApps() {
...
mHandler.post(new Runnable() {
public void run() {
final long bindTime = SystemClock.uptimeMillis();
final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
callbacks.bindAllApplications(added);
}
});...}
调用callbacks的bindAllApplications函数,在前面我们得知这个callbacks实际是指向Launcher的,因此我们来查看Launcher的bindAllApplications函数:
//Launcher
public void bindAllApplications(final ArrayList<AppInfo> apps) {
mAppsView.setApps(apps);//
mLauncherCallbacks.bindAllApplications(apps);
}
那mAppsView是什么?
mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
apps_view对应的是一个自定义控件:
com.android.launcher3.allapps.AllAppsContainerView
public AllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
Resources res = context.getResources();
mLauncher = (Launcher) context;
mSectionNamesMargin = res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin);
mApps = new AlphabeticalAppsList(context);
mAdapter = new AllAppsGridAdapter(mLauncher, mApps, this, mLauncher, this);
mApps.setAdapter(mAdapter);
mLayoutManager = mAdapter.getLayoutManager();
mItemDecoration = mAdapter.getItemDecoration();
mRecyclerViewTopBottomPadding =
res.getDimensionPixelSize(R.dimen.all_apps_list_top_bottom_padding);
mSearchQueryBuilder = new SpannableStringBuilder();
Selection.setSelection(mSearchQueryBuilder, 0);
}
再看看mApps初始化的地方:
publicAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {Resourcesres= context.getResources(); mLauncher = (Launcher) context; mSectionNamesMargin = res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin); mApps = newAlphabeticalAppsList(context); mAdapter = newAllAppsGridAdapter(mLauncher, mApps, this, mLauncher, this); mApps.setAdapter(mAdapter); mLayoutManager = mAdapter.getLayoutManager(); mItemDecoration = mAdapter.getItemDecoration(); mRecyclerViewTopBottomPadding = res.getDimensionPixelSize(R.dimen.all_apps_list_top_bottom_padding); mSearchQueryBuilder = newSpannableStringBuilder(); Selection.setSelection(mSearchQueryBuilder, 0);}
最后再看看AllAppsContainerView的onFinishInflate方法:
//AllAppsContainerView
@Override
protected void onFinishInflate() {
super.onFinishInflate();
...
// Load the all apps recycler view
mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);
mAppsRecyclerView.setApps(mApps);//2
mAppsRecyclerView.setLayoutManager(mLayoutManager);
mAppsRecyclerView.setAdapter(mAdapter);//3
mAppsRecyclerView.setHasFixedSize(true);
mAppsRecyclerView.addOnScrollListener(mElevationController);
mAppsRecyclerView.setElevationController(mElevationController);
...
}
onFinishInflate函数在加载完xml文件时就会调用。AllAppsRecyclerView设置数据,并setAdapter。
一张图总结Launcher整个启动过程以及数据显示过程: