完整的启动过程:
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完成自己的使命
notes: 这部分内部不主要。只要把上面的几个图看懂. 知道init启动zygote. zygote创建systemserver,然后等待其他创建进程request. systemserver进程启动60个services.
图解: Android系统启动过程由上图从下往上的一个过程:Loader -> Kernel -> Native -> Framework -> App,接来下按从下到上的顺序简要介绍下每层:
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生成的。
Android系统启动(二)-Init篇
经过前面的开篇介绍,我们对android系统启动有了一个初步的了解.那么接下来会详细分析几个关键过程.
一、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。
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Android系统启动(三)-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原物理地址中复制内容到一块新的物理地址上,供应用程序进程使用。这样子进程可以高效而完整地继承父进程内存地址中的数据。
Android系统启动(四)-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();
三、系统服务
startBootstrapServices:引导服务
服务 | 作用 |
---|---|
Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |
ActivityManagerService | 负责四大组件的启动、切换、调度。 |
PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
LightsService | 管理和显示背光LED |
DisplayManagerService | 用来管理所有显示设备 |
UserManagerService | 多用户模式管理 |
SensorService | 为系统提供各种感应器服务 |
PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操作 |
startCoreServices:核心服务
服务 | 作用 |
---|---|
BatteryService | 管理电池相关的服务 |
UsageStatsService | 收集用户使用每一个APP的频率、使用时常 |
WebViewUpdateService | WebView更新服务 |
startOtherServices:其他服务(60多种)
服务 | 作用 |
---|---|
CameraService | 摄像头相关服务 |
AlarmManagerService | 全局定时器管理服务 |
InputManagerService | 管理输入事件 |
WindowManagerService | 窗口管理服务 |
VrManagerService | VR模式管理服务 |
BluetoothService | 蓝牙管理服务 |
NotificationManagerService | 通知管理服务 |
DeviceStorageMonitorService | 存储相关管理服务 |
LocationManagerService | 定位管理服务 |
AudioService | 音频相关管理服务 |
… | …. |
四、SystemServiceManager分析
从名字就很明显知道SystemServiceManager是系统服务管理类,简单了解两个方法:
4.1 startService函数
很简单,就是通过反射创建服务对象,并调用其onStart( )方法启动。
4.2 startBootPhase函数
Systemserver会将设备启动分成几个阶段,每个阶段service通过继承SytemService实现的onBootPhase方法来做一些对应的操作,相当于一个回调。
Android系统启动(五)-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的的创建与启动。
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);
...
//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) {
....
updateCpuStatsNow(); //更新CPU状态
}}}};...}
首先,创建了一个名为“ActivityManager”的消息循环线程,不断地接收其他进程发给AMS的消息;并把该消息循环线程与MainHandler绑定,这样,由MainHandler完成消息的具体处理。
然后,创建了一些服务,并在/data/system目录下创建该服务需要的文件或文件夹,具体如下:
服务 | 服务说明 | 文件 | 文件说明 |
---|---|---|---|
BatteryStatsService | 电池状态管理 | /data/system/batterystats.bin | 记录包括电压在内的各种电池信息 |
ProcessStatsService | 进程状态管理 | /data/system/procstats | 记录各个进程的状态信息 |
AppOpsService | 应用操作权限管理 | /data/system/appops.xml | 存储各个app的权限设置和操作信息 |
1.2.2 ActivityManagerService.setSystemProcess
首先,向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了。
二、startOtherServices( )
2.1 systemServer触发的AMS准备工作:
private void startOtherServices() {
...
//移除非系统的provider,安装所有的系统provider,创建核心Settings Observer,用于监控Settings的改变。
mActivityManagerService.installSystemProviders();
…
//保存WMS对象
mActivityManagerService.setWindowManager(wm);
…
//系统启动前的准备工作,启动SystemUI和Home界面等
mActivityManagerService.systemReady(new Runnable() {...});
}
2.2 mActivityManagerService.systemReady()
主要分三个阶段来讲:
public void systemReady(final Runnable goingCallback) {
before goingCallback.run()
goingCallback.run()
after goingCallback.run()
}
2.2.2 goingCallback.run()
这部分是回调到systemServer startOtherServices中完成的:
此阶段主要工作总结:
- startBootPhase:550(PHASE_ACTIVITY_MANAGER_READY),回调相应onBootPhase()方法;
- 启动WebView;
- 启动systemui服务;
- startBootPhase:600(PHASE_THIRD_PARTY_APPS_CAN_START),回调相应onBootPhase()方法;
- 执行一系列服务的systemReady方法;
- 执行一系列服务的systemRunning方法;
2.2.3 after goingCallback.run()
此阶段主要工作总结:
- 回调所有SystemService的onStartUser()方法;
- 启动persistent进程;
- 启动home Activity;
- 发送广播USER_STARTED和USER_STARTING;
- 发送广播USER_SWITCHED;
最后画了个简单时序图总结下AMS启动流程:
Android系统启动(六)-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执行的是
//LauncherApps
mService.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
//AllAppsContainerView
public void setApps(List<AppInfo> apps) {
mApps.setApps(apps);
}
再看看mApps初始化的地方:
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);
}
最后再看看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整个启动过程以及数据显示过程:
Home界面启动
待Application Framework层的ActivityManagerService准备就绪后,就会通知各个模块,继续执行上层应用。
先附一张体系结构图:
public void systemReady(final Runnable goingCallback) {
......
// Start up initial activity.
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
......
}
这样一来,就启动了Home界面,完成了整个Android启动流程。
下面是启动流程图:
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
启动zygote
启动Kernel创建init进程-->init进程fork第一个进程即Zygote进程(横穿Java和C/C++)-->Zygote创建虚拟机(调用AndroidRuntime.cpp中的startVm创建虚拟机)-->startReg完成虚拟机中的JNI方法注册
init.zygote.rc文件中,zygote服务定义如下:
zygote进程的执行流程
第一步 执行app_process的main函数
- 创建AppRuntime对象,AndroidRuntime类的主要作用是创建和初始化虚拟机。
第二步AndroidRuntime类的start()函数来执行java类。
- 调用startVm(),启动虚拟机
- 调用startReg(),注册系统的JNI函数。
- 调用ZygoteInit类的main()方法。
第三步 ZygoteInit类的main()方法的执行过程。
- 调用registerZygoteSocket()方法注册Zygote的socket监听端口,用来接收启动应用程序的消息。
调用preload()方法装载系统资源,包括系统预加载类、Framework资源和openGL的资源。
这样当应用程序被fork处理后,应用的进程内已经包含了这些系统资源,大大节省了应用的启动时间 - 调用startSystemServer()方法启动SystemServer进程
- 最后调用runSelectLoop()方法进入监听和接收消息的循环。
Android系统在启动过程中,先启动Kernel创建init进程,紧接着由init进程fork第一个横穿Java和C/C++的进程,即Zygote进程。
Zygote启动过程中在AndroidRuntime.cpp中的startVm创建虚拟机,VM创建完成后,紧接着调用startReg完成虚拟机中的JNI方法注册。
在Android中,zygote是整个系统创建新进程的核心装置,是由init进程根据init.rc文件中的配置项创建的.
所有的应用程序进程,以及用来运行系统关键服务的system进程都是由zygote进程负责创建的。
zygote在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类。
zygote与系统中其它进程的通信没有使用Binder,而是采用了AF_UNIX类型的socket。
Zygote启动过程的调用流程图:
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
SystemServer作用
SystemServer由Zygote fork生成的,该进程承载着framework的核心服务.AMS etc 60多个services都在它里面启动,AMS etc service是它的线程.
system_server进程是系统进程,Java framework框架的核心载体,里面运行了大量的系统服务,比如这里提供ApplicationThreadProxy(简称ATP),ActivityManagerService(简称AMS),这个两个服务都运行在system_server进程的不同线程中,由于ATP和AMS都是基于IBinder接口,都是binder线程,binder线程的创建与销毁都是由binder驱动来决定的。
SystemServer 是 Android JAVA 层的系统服务模块,管理system service.
System Server负责启动和管理整个framework,基本上在Framework中的大多数service都是在system server进程中的一个线程。比如平时开发接触比较多的ActivityManagerService,PackageManagerService ,WindowManagerService等。
每个进程app or system_server都有一个application.
理解Application创建过程已介绍过createSystemContext()过程, 该过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application
启动SystemServer进程
启动流程图如下:
上图前4步骤(即颜色为紫色的流程)运行在是Zygote
进程,从第5步(即颜色为蓝色的流程)ZygoteInit.handleSystemServerProcess开始是运行在新创建的system_server
,这是fork机制实现的(fork会返回2次)
System进程的主线程负责启动Binder线程池,以及UI渲染线程. UI渲染线程负责启动控制台事件监控线程。
在这三种类型的线程中,UI渲染线程是主角,Binder线程和控制台事件监控线程是配角。
Binder线程池是为了让其它进程,例如Android应用程序进程,可以与SurfaceFlinger服务进行Binder进程间通信的,
这样运行在System进程中的系统关系服务就可以与其它进程执行Binder进程间通信了。
System_server 源码分析
private void run() {
// 主线程looper就在当前线程运行
Looper.prepareMainLooper();
//初始化系统上下文 【见小节1.3】
createSystemContext();
//创建系统服务管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//启动各种系统服务
startBootstrapServices(); // 启动引导服务【见小节1.4】
startCoreServices(); // 启动核心服务【见小节1.5】
startOtherServices(); // 启动其他服务【见小节1.6】
//一直循环执行
Looper.loop();
}
startBootstrapServices etc 函数启动这些services 线程
private void startBootstrapServices() {
//阻塞等待与installd建立socket通道
Installer installer = mSystemServiceManager.startService(Installer.class);
//启动服务ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
//启动服务PowerManagerService
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
//启动服务DisplayManagerService
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//启动服务PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
//设置AMS
mActivityManagerService.setSystemProcess();
//启动传感器服务
startSensorService();
.......
}
该方法所创建的服务:ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服务.
System_server主线程的启动工作总算完成, 进入Looper.loop()状态(for+epoll),等待其他线程通过handler发送消息到主线再处理.
空闲block在epoll,有消息则循环从queue读取并处理.
call ladder :
at android.os.MessageQueue.nativePollOnce(Native method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:135)
at com.android.server.SystemServer.run(SystemServer.java:290)
at com.android.server.SystemServer.main(SystemServer.java:175)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
下面的操作运行在App进程
Process.start()方法是阻塞操作,等待直到进程创建完成并返回相应的新进程pid,才完成该方法。
当App第一次启动时或者启动远程Service,即AndroidManifest.xml文件中定义了process:remote属性时,都需要创建进程。比如当用户点击桌面的某个App图标,桌面本身是一个app(即Launcher App),那么Launcher所在进程便是这次创建新进程的发起进程,该通过binder发送消息给system_server进程,该进程承载着整个java framework的核心服务。system_server进程从Process.start开始,执行创建进程,流程图(以进程的视角)如下:
上图中,system_server
进程通过socket IPC通道向zygote
进程通信,zygote
在fork出新进程后由于fork调用一次,返回两次,即在zygote进程中调用一次,在zygote进程和子进程中各返回一次,从而能进入子进程来执行代码。该调用流程图的过程:
- system_server进程(
即流程1~3
):通过Process.start()方法发起创建新进程请求,会先收集各种新进程uid、gid、nice-name等相关的参数,然后通过socket通道发送给zygote进程; - zygote进程(
即流程4~12
):接收到system_server进程发送过来的参数后封装成Arguments对象,图中绿色框forkAndSpecialize()方法是进程创建过程中最为核心的一个环节(详见流程6),其具体工作是依次执行下面的3个方法:- preFork():先停止Zygote的4个Daemon子线程(java堆内存整理线程、对线下引用队列线程、析构线程以及监控线程)的运行以及初始化gc堆;
- nativeForkAndSpecialize():调用linux的fork()出新进程,创建Java堆处理的线程池,重置gc性能数据,设置进程的信号处理函数,启动JDWP线程;
- postForkCommon():在启动之前被暂停的4个Daemon子线程。
- 新进程(
即流程13~15
):进入handleChildProc()方法,设置进程名,打开binder驱动,启动新的binder线程;然后设置art虚拟机参数,再反射调用目标类的main()方法,即Activity.main()方法。
再之后的流程,如果是startActivity则将要进入Activity的onCreate/onStart/onResume等生命周期;如果是startService则将要进入Service的onCreate等生命周期。
system_server进程等待zygote返回进程创建完成(ZygoteConnection.handleParentProc), 一旦Zygote.forkAndSpecialize()方法执行完成, 那么分道扬镳, zygote告知system_server进程进程已创建, 而子进程继续执行后续的handleChildProc操作.
Tips: [小节11]RuntimeInit.java的方法nativeZygoteInit()会调用到onZygoteInit(),这个过程中有startThreadPool()创建Binder线程池。也就是说每个进程无论是否包含任何activity等组件,一定至少会包含一个Binder线程。
- App发起进程:当从桌面启动应用,则发起进程便是Launcher所在进程;当从某App内启动远程进程,则发送进程便是该App所在进程。发起进程先通过binder发送消息给system_server进程;
- system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求;
- zygote进程:在执行
ZygoteInit.main()
后便进入runSelectLoop()
循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程; - 新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。
启动Home
一旦系统服务在内存中跑起来了,Android就完成了引导过程,这个时候“ACTION_BOOT_COMPLETED”开机启动广播就会发出,Home主页启动。
App进程是应用程序所在进程,主线程主要负责Activity/Service等组件的生命周期以及UI相关操作都运行在这个线程; 另外,每个App进程中至少会有两个binder线程 ApplicationThread(简称AT)和ActivityManagerProxy(简称AMP),除了下图中所示的线程,其实还有很多线程,比如signal catcher线程等
下面材料引用blog:http://gityuan.com/
App主要是具体的UI业务需求.
AMS则是管理系统四大组件以及进程管理,尤其是Activity的各种栈以及状态切换等管理;
WMS则是管理Activiy所相应的窗口系统(系统窗口以及嵌套的子窗口);
ams和wms是属于android 系统的,不是属于一个app的。他们负责启动app.
SurfaceFlinger则是将应用UI绘制到frameBuffer(帧缓冲区),最终由硬件完成渲染到屏幕上
交互 APP-->AMS(WMS)-->SF
- App跟AMS通信,会建立Session连接到WMS,后续便通过IWindowSesson跟WMS通信;
- WMS跟SF通信,WMS建立SurfaceComposerClient,然后会在SF中创建Client与之对应, 后续便通过ISurfaceComposerClient跟SF通信
Activtiy thread
从进程与线程间通信的角度,通过一张图加深大家对App运行过程的理解
App进程则是我们常说的应用程序,主线程主要负责Activity/Service等组件的生命周期以及UI相关操作都运行在这个线程;
另外,每个App进程中至少会有两个binder线程 ApplicationThread(简称AT)和ActivityManagerProxy(简称AMP),除了图中画的线程,
其中还有很多线程,比如signal catcher线程等,这里就不一一列举。
Binder用于不同进程之间通信,由一个进程的Binder客户端向另一个进程的服务端发送事务,比如图中线程2向线程4发送事务;而handler用于同一个进程中不同线程的通信,比如图中线程4向主线程发送消息。
结合图说说Activity生命周期,比如暂停Activity,流程如下:
- 线程1的AMS中调用线程2的ATP;(由于同一个进程的线程间资源共享,可以相互直接调用,但需要注意多线程并发问题)
- 线程2通过binder传输到App进程的线程4;
- 线程4通过handler消息机制,将暂停Activity的消息发送给主线程;
- 主线程在looper.loop()中循环遍历消息,当收到暂停Activity的消息时,便将消息分发给ActivityThread.H.handleMessage()方法,再经过方法的调用,最后便会调用到Activity.onPause(),当onPause()处理完后,继续循环loop下去。
APP启动流程:
- 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求
- system_server进程接收到请求后,向zygote进程发送创建进程的请求;
- Zygote进程fork出新的子进程,即App进程;
- App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
- system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
- App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
- 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法
到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。 启动Activity较为复杂,后续计划再进一步讲解生命周期过程与系统是如何交互,以及UI渲染过程,敬请期待。
整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段:
二. Step 12 - Step 16:ActivityManagerService(AMS)--(binder)-->Launcher进入Paused状态;
三. Step 17 - Step 24:Launcher--(binder)-->ActivityManagerService(AMS),它已经准备就绪进入Paused状态,于是ActivityManagerService->new 进程-->启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行;
四. Step 25 - Step 27:ActivityThread将一个ApplicationThread类型的Binder对象传递给ActivityManagerService(AMS),以便以后ActivityManagerService(AMS)能够通过这个Binder对象和它进行通信;
五. Step 28 - Step 35:ActivityManagerService--(binder)-->ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了
六. Activity启动. Activitythread 是enter-->application oncreate-->activity 流程图
activitythread main is enter. 到application oncreate再到activity oncreate
activity oncreate and onstart 区别:oncreate 只执行一次,界面不可见。onstart界面可见,不能交互。onresume正常画图oncreate: setContentView()、findViewById();onstart : init
暂时理解为:Activitythread是一个进程,是主线程。其就是while looper 接收message处理. view是通过input 系统获取键盘和鼠标操作,通过主线程sendmessage接口给ui线程发送。
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
Looper.loop();
}
一个Activity对应一个应用窗口;每一个窗口对应一个ViewRootImpl对象;
每一个App进程对应唯一的WindowManagerGlobal对象;
WindowManagerGlobal.sWindowManagerService用于跟WMS交互.
WindowManagerGlobal.sWindowSession用于跟Session交互;
每一个App进程对应唯一的相同Session代理对象;
App可以没有Activity/PhoneWindow/DecorView,例如带悬浮窗口的Service;
Activity运行在ActivityThread所在的主线程;
DecorView是Activity所要显示的视图内容;
ViewRootImpl:管理DecorView跟WMS的交互;每次调用addView()添加窗口时,则都会创建一个ViewRootImpl对象;
引用:简述Activity与Window关系 http://gityuan.com/2017/04/16/activity-with-window/
从设计上介绍activity到windows
源码分析参考:Android系统启动-zygote篇 http://gityuan.com/2016/02/13/android-zygote/ ---这个blog写的比较详细具体
startService源码从AMS进程到service的新进程启动过程分析:https://www.jianshu.com/p/e9f579c3b6d0
Android系统启动-综述 http://gityuan.com/2016/02/01/android-booting/
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
先启动AMS,Process.sart 启动new serviceB,然后serviceB和AMS通信,然后到UI 线程
1 ActivityManagerService(AMS)的startService
2 底层调用 Process.start
Process.start()会启动service的新进程.然后导入android.app.ActivityThread类实行它的main函数。
在Android应用程序中,每一个进程对应一个ActivityThread实例,在实行main函数中,会创建一个thread实例。
所以ServiceManagerNative.asInterface(new BinderProxy())==new ServiceManagerProxy(new BinderProxy())
3 ActivityThread类的main函数:
1) main函数中创建该进程的UI线程的Looper以及loop().
2) 创建完ActivityThread,调用ActivityThread.attach函数。
在attach函数中,会调用ActivityManagerNative.getDefault().attachApplication(mAppThread)函数
得到ActivityManagerService(AMS)的远程接口,即ActivityManagerProxy。
3) mAppThread是ApplicationThread对象,它是service新进程,通过Binder驱动程序传递给ActivityManagerService(AMS)进程里.
(mAppThread(new service)----<binder>----AMS)
AMS进程通过IApplicationThread对象跟service新进程通信.
AMS进程把mAppThread设置到代理ApplicationThreadProxy的mRemote。
ActivityManagerProxy:attachApplication(app)
4 在AMS onTransact()-->父类ActivityManagerNative的onTransact(),
其中ApplicationThreadNative.asInterface(data.readStrongBinder()),返回是ApplicationThreadProxy的对象,
把之前的IApplicationThread的实例mAppThread对象(通过Binder驱动放到data里面,即data.readStrongBinder())放到ApplicationThreadProxy的mRemote.
在AMS进程里通过ApplicationThreadProxy中mRemote和service新进程通信。
((mAppThread放到ApplicationThreadProxy的mRemote<------>service新进程通信))
在AMS中的attachApplication中:mServices是ActiveServices实例对象
5 ApplicationThreadProxy的scheduleCreateService:
其中mRemote就是service新进程的ApplicationThread对象,
通过Binder驱动程序回到service新进程的ApplicationThread对象中去执行onTransact(),
6 在H类handleMessage 中:
handlerCreateService是在ActivityThread://H.CREATE_SERVICE.回到新进程的UI线程
service.onCreate(),service就起来了。
最终通过ClassLoader加载Activity类,创建对象,回调对应的生命周期,整个过程结束。
activitythread setview开始加载xml就是画各种控件。都画完了,后台buffer推到前面buffer即屏幕
ServiceManager
// ServiceManagerNative.java
static public IServiceManager asInterface(IBinder obj) {
//由于obj为BpBinder,该方法默认返回null
IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
return new ServiceManagerProxy(obj); //见下文
}
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote; //将BinderProxy保存到mRemote
}
}
所以ServiceManagerNative.asInterface(new BinderProxy())==new ServiceManagerProxy(new BinderProxy()).
mRemote为BinderProxy对象,该BinderProxy对象的成员变量mObject记录着BpBinder(0),其作为binder代理端,指向大管家serviceManager进程的服务。
ServiceManager.getIServiceManager==new ServiceManagerProxy(new BinderProxy()),此处ServiceManagerProxy简称为SMP。
framework层的ServiceManager的调用实际的工作确实交给SMP的成员变量BinderProxy;
而BinderProxy通过jni方式,最终会调用BpBinder对象;可见上层binder架构的核心功能依赖native架构的服务来完成的。
SM管理所有service。-------所有server使用
client与service通信都需要先通过sm获取info
binder如何获取,比如system_server进程的input server 通信,需要app UI线程创建input client.
binder通信,如果获取binder client呢,通过sm register?
sm有所有service的binder info ?