一、init进程中解析init.rc,启动zygote服务进程

Zygote进程是Android和Java世界的开创者。
在Android系统中,所有的应用进程和SystemServer进程都是由Zygote进程fork而来。
Zygote进程相当于Android系统的根进程,但是事实上它也是由Linux系统的init进程启动的。
各个进程的先后顺序为:
init进程 –-> Zygote进程 –> SystemServer进程 –>应用进程

Zygote进程在init进程启动过程中被以service服务的形式启动:

init.rc中有这么一句,

     service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server     class main     socket zygote stream 660 root system

第一行表示zygote进程是以服务的形式启动的,其对应的可执行程序是/system/bin/app_process,后面四个参数是它的启动参数。

第二行表示在Zygote启动过程中,要在其内部创建一个名为zygote的socket,它在Linux下的权限是666,即所有用户多可以对它进行读写。

因为Zygote是以service的形式启动,所以在init启动过程中,android-5.1.0_r3\android5.1\system\core\init\init.c的service_start()函数会被调用。

service_start函数的主要工作是:

•通过fork()方法创建一个新的子线程,即Zygote进程
•调用create_socket()函数创建启动脚本中的zygote socket,并保存该socket的int型的文件描述符。创建时,还会为此socket创建一个类型为AF_UNIX的Socket地址,并调用bind()方法将socket与此地址进行绑定。该socket还有一个对应的设备文件,/dev/socket/zygote。

•创建完socket后,会调用publish_socket()函数将该socket发布到系统中。采用环境变量的方式,ANDROID_SOCKET_zygote – socket的文件描述符。
•调用execve(svc->args[0]),执行app_process的主程序app_main.cpp。

app_main.cpp的main函数的主要工作是:

•通过调用AppRuntime::start()函数,通过JNI的方式,进一步启动Zygote:
AppRuntime.start(“com.android.internal.os.ZygoteInit”, args);args是参数列表,
其中较重要的是标记是否要启动System进程、记录socket名称。

ZygoteInit的main函数的主要工作是:

1、初始化DDMS
2、注册Zygote进程的Socket
3、调用registerZygoteSocket(“zygote”)函数获取到zygote socket文件描述,并根据此描述符创建一个本地服务Socket:LocalServerSocket。
这个服务Socket是用来等待Activity管理服务ActivityManagerService请求Zygote进程创建新的应用程序进程的。
4、加载framework的class、resource、OpenGL、WebView等各种系统资源
5、fork出SystemServer进程
6、启动SystemServer进程,上述的"–runtime-init"表示需要提供Binder服务,Binder服务正是在此进程。
7、最后进入runSelectLoop(),循环监听Socket信息,收到创建应用程序Socket消息,在runOnce()中调用Zygote#forkAndSpecialize()创建和启动应用进程
查看AMS代码,会看到AMS启动应用进程,就是通过socket与zygote进程通信,通知zygote进程去孵化应用进程
Zygote 会监听其 Socket (/dev/socket/zygote) 来判断是否需要启动 App。
每当监听到需要创建 App 的请求时,就 fork 一个进程即可。
fork出的应用进程,便继承了父进程zygote进程的已加载资源,所有的framework.jar的 Class 、so和 res资源,立即拥有,无需再重新加载

SystemServer的main函数的主要工作是:

•启动一个线程,启动系统的关键服务。

一旦系统服务在内存中跑起来了,Android就完成了引导过程。在这个时候“ACTION_BOOT_COMPLETED”开机启动广播就会发出去。

二、在ActivityManagerService中启动Home应用

ActivityManagerService.javapublic void systemReady(final Runnable goingCallback) {    ......    // Start up initial activity.    mBooting = true;    startHomeActivityLocked(mCurrentUserId, "systemReady");    ......}

startHomeActivityLocked()方法会向PMS查询具有HOME类别的应用,即在AndroidManifest.xml有如下的声明

取其中一个包名,然后启动之,此后便是应用进程启动的部分了。

三、应用进程、主线程的启动

接上,AMS确定HOME应用,找到目标HOME的Activity之后,发出intent启动之,走正常的Activity启动流程。

Activity启动流程

这里,HOME首次启动时,Launcher进程不存在,所以,
AMS通过socket向Zygote进程发送启动进程的命令,从Zygote进程fork出子进程作为应用程序的进程,之后跑主线程,加载应用进程ActivityThread.java类去进行,入口是ActivityThread.main()

应用进程,主线程启动后,ActivityThread.main()里干的就是,与AMS,SMS,WMS等各种相关系统服务搭建通信桥梁,之后 ,进入Looper.loop()的主线程消息死循环!
(这便是主线程,消息循环,Handler的奥秘所在)

而后,回到AMS启动HOME目标Activity,它启动完目标进程后,消息通信了建立了,于是乎,向目标Launcher进程,发送启动目标Activity的消息

最后,ActivityThread主线程接到消息后,创建目标Activity的实例,进行一系列的Create动作(主要是创建View,窗口等),调用其生命周期,便开始了应用界面之旅…

此后,应用进程所有的事件,严重依赖其与AMS的Binder消息通道(四大组件的消息,各种广播,各种事件,都是从此消息通道过来),而主线程则一直在Handler/Looper消息循环机制中,所以应用进程,在主线程,最好只作消息处理,部分轻量UI处理,其余的,都要子线程来处理。

附:拓展

  • 为何在 Android 中 fork Zygote 进程如此高效了?
    Linux Kernel 采用了 Copy-On-Write 的技术,Copy-On-Write 的意思是只有在写的时候才单独复制一份,而读的时候不进行操作。 换而言之 fork zygote 实际上并未实际复制什么东西,只有在发生写操作时,才单独复制一份。而另一方面,class 和 Resource 资源文件并不需要重新写,这些文件在绝大多数时候都是只读的。
    最后,实际的效果就是尽管运行着多个 APP,但实际只有一份 class 和 resource 文件在 Zygote 进程中。

  • 关于 preloadClassed “preloaded-classes”
    是一个简单的包含一系列需要预加载类的文本文件
    你可以在/frameworks/base找到“preloaded-classes”文件。
    preloadResources() preloadResources也意味着本地主题、布局以及android.R文件中包含的所有东西都会用这个方法加载。

更多相关文章

  1. Android应用开发之RelativeLayout (相对布局)+梅花效果案例
  2. android 程序启动界面的短暂黑屏解决办法
  3. Android完全退出程序研究
  4. 史上最详细的Android系统SystemUI 启动过程详细解析
  5. 为什么iOS比Android更吸引开发者
  6. 【Android(安卓)性能优化】应用启动优化 ( 安卓应用启动分析 | L
  7. Android启动脚本init.rc(1)
  8. android进程间共享简单数据
  9. 在Ubuntu中和Android中添加开机自启动的守护进程

随机推荐

  1. 网站301跳转问题的探讨和用法,网站做301跳
  2. 维度规约(降维)算法在WEKA中应用
  3. 亚马逊商品销售数据爬虫分析报告
  4. 百度指数是什么意思?其中的数值又代表什么
  5. 时间序列建模三部曲
  6. 二手闲置物品交易数据快照
  7. 百度蜘蛛ip地址大全,百度搜索引擎蜘蛛的IP
  8. 用Rapidminer做文本挖掘的应用:情感分析
  9. 如何爬取百度热榜,百度热榜可以抓取吗
  10. 常用的几款抓包工具_ 常见的4种抓包工具