前言
之前简单总结了下Android启动流程,这里从源码的角度再具体分析每一步都做了什么?
源码分析
这里从 init的入口函数main.cpp的main方法
开始分析
- init的入口函数main.cpp的main方法
// 路径:system/core/init/main.cpp
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
__asan_set_error_report_callback(AsanReportCallback);
#endif
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
}
if (argc > 1) {
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
return SubcontextMain(argc, argv, &function_map);
}
if (!strcmp(argv[1], "selinux_setup")) {
return SetupSelinux(argv);
}
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);
}
}
return FirstStageMain(argc, argv);
}
这里我们主要看下SecondStageMain(argc, argv)
// 路径:system/core/init/init.cpp
int SecondStageMain(int argc, char** argv) {
...
//用来存放解析出的内容
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
//在这个方法中会对 /system/core/rootdir/init.rc 脚本文件文件进行解析
LoadBootScripts(am, sm);
//循环处理init.rc脚本中的command命令,处理完就进入等待
while (true) {
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running()))
{
//内部遍历执行每个action中携带的command对应的执行函数
am.ExecuteOneCommand();
}
}
...
}
init.rc
// 位置:system/core/rootdir/init.rc
start servicemanager
start zygote
可见,init进程会启动ServiceManager和Zygote进程
;
- 我们在看下启动Zygote对应的参数配置
// 位置:system/core/rootdir/init.zygote32.rc
...
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
...
- 而zygote进程的入口处理函数是app_main.cpp中的main()函数;
//位置:/frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]) //这里入参是--zygote --start-system-server
{
...
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i;
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME; //赋值niceName为Zygote,之前实际是app_process
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
...
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string(), true /* setProcName */);//最终,设置进程名为Zygote
}
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote); //启动进程
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
之前代码都在Native层,之后都是在Java层
ZygoteInit
public static void main(String argv[]) {
//参数会传递过来,因此startSystemServer = true enableLazyPreload =false
ZygoteServer zygoteServer = null;
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
...
if (!enableLazyPreload) {
//由于enableLazyPreload == false,所以这里代码执行
这里做预加载工作:
1.加载系统类 "/system/etc/preloaded-classes”,如android.accounts.*/android.animation.*/android.app.*
2.加载资源文件;
3.加载一些so;
4. ...
preload(bootTimingsTraceLog);
}
zygoteServer = new ZygoteServer(isPrimaryZygote); //内部通过LocalServerSocket实现进程间通信
if (startSystemServer) {
//fork SystemServer进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
if (caller != null) {
caller.run();
}
}
从上面代码中看出,Zygote进程主要做了以下几件事:
1. 预加载系统类、资源等工作;
创建ZygoteServer对象实现进程间通信
,内部是通过ServerSocket实现的;那为什么不通过Binder实现呢??
对于这个问题可以查看:android中AMS通知Zygote去fork进程为什么使用socket而不使用binder?
简单小结下主要是以下几点原因:
a. 启动先后顺序问题,由于ServiceManager和Zygote是不同进程,无法保证时序,我们知道使用Binder需要先注册到ServiceManager;
b. 多线程问题,zygote如果使用binder,会导致子进程中binder线程的挂起和锁状态不可恢复;
c. 效率问题,binder虽说内存拷贝只有一次,但由于涉及到安全验证等等环节,效率实际比LocalSocket低;
d. 安全问题,LocalSocket同样支持权限验证,也是安全的;
e. .Binder拷贝问题;
fork SystemServer进程;
- SystemServer进程,主要是调用
run方法
...
startBootstrapServices(t); //启动AMS/PMS/PowerMangerService等等;
startCoreServices(t);
startOtherServices(t);
...
由此可见,AMS/PMS是由SystemServer进程启动,同时我们查看AMS、PMS代码他们并没有main函数,因此和SystemServer进程是同一进程
结语
如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )