http://www.jianshu.com/p/6037f6fda285

zygote是什么?有什么作用?

zygote意为“受精卵“。

在Android系统里面,zygote是一个进程的名字。Android是基于Linux System的,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。在Linux System里面,所有的进程都是由init进程fork出来的,我们的zygote进程也不例外。

所以当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的。所以说,除了第一个zygote进程,其他应用所在的进程都是zygote的子进程,这下你明白为什么这个进程叫“受精卵”了吧?因为就像是一个受精卵一样,它能快速的分裂,并且产生遗传物质一样的细胞!

SystemServer是什么?有什么作用?它与zygote的关系是什么?

SystemServer也是一个进程,而且是由zygote进程fork出来的。

系统里面重要的服务都是在这个进程里面开启的,比如
ActivityManagerService、PackageManagerService、WindowManagerService等等

public final class SystemServer {

    //zygote的主入口
public static void main(String[] args) {
new SystemServer().run();
} public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
} private void run() { ...ignore some code... //加载本地系统服务库,并进行初始化
System.loadLibrary("android_servers");
nativeInit(); // 创建系统上下文
createSystemContext(); //初始化SystemServiceManager对象,下面的系统服务开启都需要调用SystemServiceManager.startService(Class<T>),这个方法通过反射来启动对应的服务
mSystemServiceManager = new SystemServiceManager(mSystemContext); //开启服务
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} ...ignore some code... } //初始化系统上下文对象mSystemContext,并设置默认的主题,mSystemContext实际上是一个ContextImpl对象。调用ActivityThread.systemMain()的时候,会调用ActivityThread.attach(true),而在attach()里面,则创建了Application对象,并调用了Application.onCreate()。
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
} //在这里开启了几个核心的服务,因为这些服务之间相互依赖,所以都放在了这个方法里面。
private void startBootstrapServices() { ...ignore some code... //初始化ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager); //初始化PowerManagerService,因为其他服务需要依赖这个Service,因此需要尽快的初始化
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // 现在电源管理已经开启,ActivityManagerService负责电源管理功能
mActivityManagerService.initPowerManagement(); // 初始化DisplayManagerService
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); //初始化PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); ...ignore some code... } }

这段代码很重要。

看完下面的你就知道为什么了。

ActivityManagerService是什么?什么时候初始化的?有什么作用?

ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。

ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService。

而且在这之前,调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。注意,这是系统进程开启时的流程,在这之后,会开启系统的Launcher程序,完成系统界面的加载与显示。

那么AMS有什么用呢?在前面我们知道了,如果想打开一个App的话,需要AMS去通知zygote进程,除此之外,其实所有的Activity的开启、暂停、关闭都需要AMS来控制,所以我们说,AMS负责系统中所有Activity的生命周期。

Launcher是什么?什么时候启动的?

当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。Launcher本质上也是一个应用程序。

当我们点击一个图标时,最终其实就是

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, opts.toBundle());

所以我们现在明确了,Launcher中开启一个App,其实和我们在Activity中直接startActivity()基本一样,都是调用了Activity.startActivityForResult()。

Instrumentation是什么?和ActivityThread是什么关系?

还记得前面说过的Instrumentation对象吗?每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()

Instrumentation意为“仪器”,这个类就是完成对Application和Activity初始化和生命周期的工具类。

AMS是董事会,负责指挥和调度的,ActivityThread是老板,虽然说家里的事自己说了算,但是需要听从AMS的指挥,而Instrumentation则是老板娘,负责家里的大事小事,但是一般不抛头露面,听一家之主ActivityThread的安排。

如何理解AMS和ActivityThread之间的Binder通信?

AMS和ActivityThread之间是用Binder通信的。很明显AMS是服务器端,而AT是客户端。

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{ //从类声明上,我们可以看到ActivityManagerNative是Binder的一个子类,而且实现了IActivityManager接口
static public IActivityManager getDefault() {
return gDefault.get();
} //通过单例模式获取一个IActivityManager对象,这个对象通过asInterface(b)获得
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
} //最终返回的还是一个ActivityManagerProxy对象
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
} //这里面的Binder类型的obj参数会作为ActivityManagerProxy的成员变量保存为mRemote成员变量,负责进行IPC通信
return new ActivityManagerProxy(obj);
} }

AMS的Binder对象就是ActivityManagerNative,而IActivityManager是一个IInterface,它代表远程Service具有什么能力。ActivityManagerProxy就是AMS的远程接口。

客户端:ActivityManagerProxy =====>Binder驱动=====> ActivityManagerService:服务器

但是!这里Binder通信是单方向的,即从ActivityManagerProxy指向ActivityManagerService的,如果AMS想要通知ActivityThread做一些事情,应该咋办呢?

还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread和ApplicationThreadProxy。他们也都实现了相同的接口IApplicationThread

客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器

AMS接收到客户端的请求之后,会如何开启一个Activity?

至此,点击桌面图标调用startActivity(),终于把数据和要开启Activity的请求发送到了AMS了。

AMS的startActivity最终会调用到ActivityStack的startActivityLocked(ActivityRecord r, boolean newTask,boolean doResume, boolean keepCurTransition, Bundle options)

ActivityRecord代表的就是要开启的Activity对象,里面分装了很多信息,比如所在的ActivityTask等,如果这是首次打开应用,那么这个Activity会被放到ActivityTask的栈顶

送给你们的彩蛋

不要使用 startActivityForResult(intent,RESULT_OK)

这是因为startActivity()是这样实现的

public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public static final int RESULT_OK  = -1;

所以

startActivityForResult(intent,RESULT_OK) = startActivity()

你不可能从onActivityResult()里面收到任何回调。

一个App的程序入口到底是什么?

是ActivityThread.main()。

整个App的主线程的消息循环是在哪里创建的?

是在ActivityThread初始化的时候,就已经创建消息循环了,所以在主线程里面创建Handler不需要指定Looper,而如果在其他线程使用Handler,则需要单独使用Looper.prepare()和Looper.loop()创建消息循环。

Application是在什么时候创建的?onCreate()什么时候调用的?

也是在ActivityThread.main()的时候,再具体点呢,就是在thread.attach(false)的时候。

参考文章

下面的这些文章都是这方面比较精品的,希望你抽出时间研究,这可能需要花费很长时间,但是如果你想进阶为中高级开发者,这一步是必须的。

再次感谢下面这些文章的作者的分享精神。

Binder

zygote

ActivityThread、Instrumentation、AMS

Launcher

Android-Activity启动流程的更多相关文章

  1. Android Activity启动流程, app启动流程,APK打包流程, APK安装过程

    1.Activity启动流程 (7.0版本之前) 从startActivity()开始,最终都会调用startActivityForResult() 在该方法里面会调用Instrumentation. ...

  2. Cocos2d-x3.3RC0的Android编译Activity启动流程分析

    本文将从引擎源代码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,以下是具体分析. 1.引擎源代码Jni.部分Java层和C++层代码分析 watermark/2 ...

  3. Android Activity启动流程源码全解析(1)

    前言 Activity是Android四大组件的老大,我们对它的生命周期方法调用顺序都烂熟于心了,可是这些生命周期方法到底是怎么调用的呢?在启动它的时候会用到startActivty这个方法,但是这个 ...

  4. 《转》深入理解Activity启动流程(三)–Activity启动的详细流程2

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  5. 《转》深入理解Activity启动流程(三)–Activity启动的详细流程1

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  6. 《转》深入理解Activity启动流程(二)–Activity启动相关类的类图

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先为大家介绍Act ...

  7. 《转》深入理解Activity启动流程(一)–Activity启动的概要流程

    本文原创作者:Cloud Chou. 原文地址:http://www.cloudchou.com/android/post-788.html Android中启动某个Activity,将先启动Acti ...

  8. 深入理解Activity启动流程(三)–Activity启动的详细流程2

    本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--A ...

  9. 深入理解Activity启动流程(二)–Activity启动相关类的类图

    本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先 ...

  10. 深入理解Activity启动流程(一)–Activity启动的概要流程

    概述 Android中启动某个Activity,将先启动Activity所在的应用.应用启动时会启动一个以应用包名为进程名的进程,该进程有一个主线程,叫ActivityThread,也叫做UI线程. ...

随机推荐

  1. 阻止事件冒泡,阻止默认事件,event.stopPropagation()和event.preventDefault(),return false的区别

    1.event.stopPropagation()方法 这是阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开, ...

  2. IOS渗透测试第一步-基础知识统一放送

    原文: http://www.websecgeeks.com/2017/04/ios-application-pentesting-part-3.html http://www.websecgeeks ...

  3. 转载:TCP/IP四层模型

    转载:TCP/IP四层模型 一. TCP/IP参考模型示意图 ISO制定的OSI参考模型的过于庞大.复杂招致了许多批评.与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用. 如图所示 ...

  4. python线程死锁与递归锁

    死锁现象 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去. 此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待 ...

  5. [LeetCode] Z字型变换

    题目内容: 将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数: P A H N A P L S I I G Y I R 之后从左往右,逐行读取字符:" ...

  6. 【xsy3355】图 思维

    题目大意:给你一个n个点m条无向边的图,问这个图是否能够: 1,被四染色(用四种颜色给图染色,且相邻点颜色不同). 2,找出一个奇环,满足在原图中去掉这个奇环后每个点依然相邻. 请输出1或者2中的任意 ...

  7. android开发学习——day7

    线性布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...

  8. chromium浏览器开发系列第三篇:chromium源码目录结构

    上两篇介绍了下载源码和编译源码,这次主要介绍chromium的源码目录结构,我也是通过源码和官网结合来跟大家说,如果有说的不准确的,欢迎交流. 另外,官网的不一定准确,他们其实也很懒,所以最主要还是靠 ...

  9. 前端通信:ajax设计方案(八)--- 设计请求池,复用请求,让前端通信快、更快、再快一点

    直接进入主题,本篇文章有点长,包括从设计阶段,到摸索阶段,再到实现阶段,最后全面覆盖测试阶段(包括数据搜集清洗),还有与主流前端通信框架进行对比PK阶段. 首先介绍一下一些概念: 1. 浏览器的并发能 ...

  10. 系统启动时队列自动下单--ServletContextListener

    package com.liying.pear.queue; import javax.servlet.ServletContextEvent; import javax.servlet.Servle ...