一些基本概念
1:ActivityManagerServices,简称AMS,服务端对象,负责系统中所有Activity的生命周期
2:ActivityThread,App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作。
3:ApplicationThread,用来实现ActivityManagerService与ActivityThread之间的交互,在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象和ActivityThread通讯。
4:ApplicationThreadProxy,是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯,AMS就是通过该代理和ActivityThread进行通讯的。
5:Instrumentation,每一个应用程序只有一个Instrumentation,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用程序的管家,ActivityThread要创建或者暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
6:ActivityStack,Activity在AMS中的栈管理,用来记录已经启动了的Activity的先后关系、状态信息等。通过ActivityStack决定是否需要启动新的进程。
7:ActivityRecord,ActivityStack的管理对象,每个Activity在AMS中对应一个ActivityRecord来记录Activity的状态以及其他的管理信息。其实就是服务端的Activity对象的映像。
8:TaskRecord,AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord来确保Activity的启动和退出的顺序。就是对应Activity的4种launchMode。
一些问题
1:zygote是什么?有什么作用?
zygote意为“受精卵”。Android是基于Linux系统的,而在Linux中,所有的进程都是由init进程直接或者间接的fork出来的,zygote进程也不例外。在Android系统中,zygote是一个进程的名称,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个“init”进程,在Linux系统中,所有的进程都是由”init”进程fork出来的,zygote进程也不例外。每一个App其实都是一个单独的dalvik虚拟机,既一个单独的进程。所以当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程,而为了实现资源公用和更快的启动速度,Android系统开启新的进程的方式,是通过fork第一个zygote进程是实现的,so,除了第一个zygote进程,其他的进程都是zygote的子进程,这就是“受精卵”的意思了。
2:SystemServer是什么?有什么作用?它和zygote有什么关系?
首先要说的是,SystemServer也是一个进程,而且它是由zygote进程fork出来的。这个进程进程是Android Framework里面的两大重要进程之一 (另外一个就是zygote进程)。为什么说SystemServe重要呢?因为系统里面重要的服务都是在这个进程中开启的,比如ActivityManagerService、PackageMangerService、WindowMangerService等等。下面来看开启的代码:
public static void main(String argv[]) {
//在加载首个zygote的时候,会传入初始化参数,使得startSystemServer = true
boolean startSystemServer = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = 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)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
//开始fork SystemServer进程
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
}
接下来看看startSystemServer()做了些什么:
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true;
}
3:ActivityManagerService是什么?有什么作用?什么时候初始化?
在上面已经简单的解释了ActivityManagerService是什么,它初始化的时机也很明确,就是在SystemServer进程开启的时候,下面从代码中来看:
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() {
//加载本地系统服务库,并进行初始化
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;
}
}
/*
* 初始化系统上下文对象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() {
//初始化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);
}
}
经过上面的步骤,我们的ActivityManagerService对象已经创建好了,并且完成了成员变量的初始化。而且,在这之前,调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。这是系统进程开启时的流程,在这之后,会开启系统的Launch程序,完成系统界面的加载和显示。
4:上面我们提到了,AMS是服务端对象,Android系统中的服务端和客户端又是什么?
其实服务端和客户端的概念不仅仅只存在Web中,在Android的框架设计中也是使用的这种模式。服务端指的就是所有App公用的系统服务,比如我们这里提到的ActivityManagerService,和前面提到的PackageManagerService、WindowManagerService等等,这些基础的系统服务是被所有App公用的,当某个App想实现某个操作的时候,要告诉这些系统服务,比如你想打开一个App,那么我们知道了包名和MainActivity类名之后就可以打开了。看下面的代码:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName cn = new ComponentName(packageName, className);
intent.setComponent(cn);
startActivity(intent);
但是,我们的App通过调用startActivity()并不能直接打开另外一个App,这个方法会通过一系列的调用,最后还是告诉AMS说:“我要打开这个App,我知道它的住址和名字,你帮我打开它”,所以是AMS来通知zygote进程来fork一个新的进程来开启我们的目标App的。这就像浏览器想打开一个超链接一样,浏览器把网页地址发送给服务器,然后还是服务器把需要的资源文件发送给客户端。
知道了Android Framework的服务-客户端架构之后,我们还需要了解一件事情,那就是我们的App和AMS(SystemServer)还有zygote进程分属三个独立的进程,它们之间如何通信?
App和AMS通过Binder进行IPC通信,AMS和zygote通过Socket进行IPC通信,通过前面我们知道,如果想要打开一个App,需要AMS去通知zygote进程,除此之外,其实所有Activity的开启、暂停、关闭都需要AMS来控制,所以说,AMS负责整个系统中所有Activity的生命周期。
在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程来具体完成。
最后一个问题:Instrumentation是什么?有什么作用?它和ActivityThread又有什么关系?
前面说过,每个Activity都会持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象,当startActivityForResult()调用的时候,实际上还是调用了mInstrumentation.execStartActivity(),来看startActivityForResult()的实现:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
...ignore some code...
} else {
if (options != null) {
//当现在的Activity有父Activity的时候会调用,但是在startActivityFromChild()内部实际还是调用的mInstrumentation.execStartActivity()
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
由上面的方法,我们可以看出,确实调用了mInstrumentation.execStartActivity,再来看它的方法实现:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
所以当我们在程序中调用startActivity()的 时候,实际上调用的是Instrumentation的相关的方法。
Instrumentation意为“仪器”,我们先看一下这个类里面包含哪些方法。
我们可以看到,这个类里面大部分的方法都和Application、Activity有关,它其实就是用来完成Application和Activity的初始化以及生命周期管理的工具类,比如,我们来看callActivityOnCreate()方法:
对activity.performCreate(icicle);大家可能不熟悉,但是对于Activity的入口onCreate()我想一定是熟悉的,来看performCreate()的实现:
final void performCreate(Bundle icicle) {
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
如你看到的,onCreate()方法在这里调用。既然,Instrumentation如此的重要,为何我们在开发的过程黄总却从来没有见过它,那么这里就要说到ActivityThread了,他两什么关系,举个例子(不知道恰当否),ActivityThread是老板,Instrumentation就是老板娘,一个主外,一个主内。ActivityThread可能大家会陌生,但是我说主线程或者UI线程,我想大家就一定不会陌生了,没错,就是它。
AMS需要暂停一个Activity,先告诉ActivityThread,再由ActivityThread告诉Instrumentation,最后由Instrumentation去执行。
以上先介绍到这里,这篇文章我也是在网上看到,实验后稍加整理出来的,感谢那些大神。