概括
先简略概括一下Activity的启动过程,以下拿点击Launcher来说。
1.开始请求执行Activity,Launcher进程发送命令到AMS
Launcher就是一个App,点击Launcher会隐式启动一个新的应用。所以跑的也是Activity.startActivity的流程。
接着就是Activity.startActivityForResult() ——> Instrumentation.execStartActivity()...一系列方法。
2.AMS执行Launcher(栈顶Activity)的onPause方法
AMS通过Binder执行Launcher的onPause方法
3.启动Activity所属的应用进程
-从Zygote中fork一个新应用进程出来。里面有负责调度ActivityRecord和Task的代码。
调度Task的算法涉及的判断很多,和当前回退栈,要启动的activity的启动模式,以及taskAffinity属性,启动Activity时设置的intent的flag等诸多要素相关
-之后会执行ActivityThread类的main方法。Activity就在这个ActivityThread实例中运行。
4.执行启动Activity
AMS通过代理,请求启动Activity。ApplicationThread通知主线程执行该请求。然后,ActivityThread执行Activity的启动,并执行它的生命周期方法。
在ApplicationThread中,对应AMS管理Activity生命周期的方法都以scheduleXXXActivity,ApplicationThread在Binder线程中,它会向主线程发送消息,ActivityThread的Handler会调用相应的handleXXXActivity方法,然后会执行performXXXActivity方法,最终调用Activity的onXXX方法。
5.AMS执行Launcher(栈顶Activity)的onStop方法
AMS通过Binder执行Launcher的onStop方法
--------------------------分割线--------------------------
前置说明:安卓众多应用来回切换,肯定不是两两应用进行通信能协调好的事,所以需要一个总管家的身份。这里就是我们的AMS。它掌管着所有Activity的生命周期。
已知AMS是运行在SystemServer这个进程上,众多Activity运行在各种应用进程中,那么问题来了...
重点一:众多Activity怎么与AMS通信的
先来两张UML图
一个图是关于ActivityManager,一个是关于ApplicationThread。
拿ActivityManager这个UML图来分析一下。ApplicationThread跟这个差不多。
我们知道用android实现IPC,写个XXX.aidl,ide会为我们生成一个同文件名不同后缀的XXX.java文件。这个文件里面的结构就像这张UML图的结构。
1.这个XXX.java类首先是一个接口,继承IInterface接口。里面一般声明了需要提供的业务方法。在这里就是IActivityManager。
2.然后XXX.java有一个内部有个抽象类Stub继承Binder实现XXX接口。在这里就是ActivityManagerNative+ActivityManagerProxy。
3.Stub里面还有内部类Proxy实现了XXX接口。在这里就是ActivityManagerProxy。
ActivityManagerNative即Stub相当于服务端。ActivityManagerProxy即Proxy相当于客户端。所以ActivityManager设计成这样的aidl结构完成通信。
再具体一点,来看看这个机制怎么完成startActivity方法。
首先是从Activity.startActivity --> Activity.startActivityForResult() --> Instrumentation.execStartActivity()
然后就会调用ActivityManagerNative.getDefault().startActivity()方法
getDefault会尝试通过ServiceManager.getService("activity")远程服务的Binder对象,然后进行asInterface转换成IActivityManager,其实返回的就是ActivityManagerProxy。
源码是这个样子的。
先看getDefault部分,使用了自带的Singleton类实现单例模式,并且声明是静态方法。
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;
}
};
static public IActivityManager getDefault() {
return gDefault.get();
}
然后看startActivity部分,类ActivityManagerProxy的startActivity方法
class ActivityManagerProxy implements IActivityManager {
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
}
里面是对参数使用Parcel序列化,然后调用transact方法,参数是方法名标识,参数,盛放返回值的容器。
这样就会跳转到ActivityManagerService的onTransact方法,ActivityManagerService会调用父类ActivityManagerNative的onTransact方法。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
}
}
所以客户端调用的方法都要经过onTransact方法转化。所以里面switch判断一下标识,就进入START_ACTIVITY_TRANSACTION的case里面。里面也有一个startActivity方法(注意此时已经位于AMS进程中了),在ActivityManagerNative这个抽象类里没有实现这个方法,所以交给AMS具体实现的方法来处理了。
所以ActivityManagerNative主要是负责Binder机制中,接受参数,转换处理参数这些功能。之后把参数整理好,才会交个AMS,AMS才是具体的处理业务的逻辑。
之后就是AMS的startActivity方法了,这里面的调用链和处理逻辑就多了。
比如判断这个新进程是不是已经启动了,不需要再从zygote中fork一个进程出来。。。。。。。。。
ps:所以在我脑里,我觉得这两张UML图附上一点业务逻辑,应该是这样。红色部分的是业务逻辑
重点二:ActivityThread的Main方法干了什么
从zygote中fork出一个新进程后,就会执行ActivityThread的main方法。
经典问题,一个App的程序入口到底是什么?回答的就是这个ActivityThread的main方法了
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
AndroidKeyStoreProvider.install();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
1.这里有关于主线程Looper的操作
我们知道如果主线程像子线程发送消息,需要有Looper.prepare()和Looper.loop()操作。
在这里就是prepareMainLooper(),因为这是主线程,这名字简直不能更形象了。
2.这里有new ActivityThread()。
3.thread.attach(false); 执行ActivityThread的attach方法。看下源码,挑出重点
private void attach(boolean system) {
...
if (!system) {
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
...
}
里面依旧ActivityManagerNative.getDefault()获取到ActivityManagerProxy。执行attachApplication方法,传的参数mAppThread类型是ApplicationThread。
这个mAppThread是在new ActivityThread()时做为成员变量同时初始化的。
然后中间过程同上面之前说的ActivityManager的binder机制调用流程,这里忽略这些流程,直接看AMS的attachApplication方法。
AMS的attachApplication方法调用attachApplicationLocked方法,里面参数就是当初传过去的ApplicationThread。
接着在这里面又用了这个ApplicationThread调用了bindApplication方法。
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean trackAllocation, boolean isRestrictedBackupMode,
boolean persistent, Configuration config, CompatibilityInfo compatInfo,
Map<String, IBinder> services, Bundle coreSettings) {
if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
最后一行看到发消息了,其实发到mH这个Handler里面。
点进去handleMessage方法,能看到很多case,比如LAUNCH_ACTIVITY, PAUSE_ACTIVITY, RESUME_ACTIVITY, DESTROY_ACTIVITY这种跟Activity相关的
还有CREATE_SERVICE, BIND_SERVICE, UNBIND_SERVICE, STOP_SERVICE跟Service相关的。
大概能猜出,这是AMS管理App的一道关卡。
我们找到BIND_APPLICATION标识,看到他进入了handleBindApplication方法里面。
private void handleBindApplication(AppBindData data) {
...
if (data.instrumentationName != null) {
...
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
...
} else {
mInstrumentation = new Instrumentation();
}
...
try {
...
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
...
}
里面有新建Instrumentation的代码,能理解,Activity的生命周期方法都是Instrumentation调用的,当然要先new一个。
然后是makeApplication这个方法,这名字+返回值是个Application,很容易猜到是创建应用的Application。进去里面一看,果然是这样。
这个创建方法需要在LoadedApk中转一手,需要需要这个类是可以读取到xml里面的自定义Application的类名字符串(如果有自定义Application的话,没有会用默认字符串“android.app.Application”)。
然后根据类的全名用反射newInstance出来一个Application。
最后调用callApplicationOnCreate,里面只有一个代码,就是执行application的onCreate方法。
所以其中一个重要流程是,运行应用Application的相关业务。接下来回到ActivityManagerService的attachApplicationLocked方法中,下一步是mStackSupervisor.attachApplicationLocked(app)。
这个app是ProcessRecord的类型,本来我觉得这是AMS(服务端)保存某一个应用(客户端)信息的实体,心里称它为“应用实体信息类”。后来发现并不能这样想,因为一个进程里面可能有多个应用的Activity,所以还是只能称为“进程实体信息类”。
attachApplicationLocked方法里面会调用realStartActivityLocked方法,里面有一句代码app.thread.scheduleLaunchActivity。这个thread是实际上是ApplicationThreadProxy类的实体,所以这句话会通过binder机制,调用到ApplicationThread里面的scheduleLaunchActivity方法。
在这个方法的后一行看到发送一个LAUNCH_ACTIVITY的消息到H这个Hander里面。找到LAUNCH_ACTIVITY这个case,我们看到执行了handleLaunchActivity方法。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity a = performLaunchActivity(r, customIntent);
...
if (a != null) {
...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
...
}
里面有两行重要的代码,重要代码一,执行perforLaunchActivity方法。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
...
return activity;
}
里面有一句mInstrumentation.newActivity方法。点进去只有一句代码,功能就是通过反射创建出一个Activity实体。
然后下面会有mInstrumentation.callActivityOnCreate方法。里面的调用链是Activity.performCreate()——>Activity.onCreate()这样就执行了我们熟悉的onCreate方法。
后面又有activity.performStart()。里面的调用链是Instrumentation.callActivityOnStart()——>Activity.onStart()。
然后回到handleLaunchActivity的重要代码二,handleResumeActivity里面的调用链是ActivityThread.performResumeActivity()——>Activity.performResume()——>Instrumentation.callActivityOnResume()——>Activity.onResume().执行了我们熟悉的onResume方法。这样Activity启动的主要流程就跑完了。
总结一下重点二。
首先想讲一下之前一直没搞清ApplicationThread和ActivityThread这两者的区别。这两个名字实在给我造成了很大的误会。
看了源码后,才知道。ActivityThread本质是主线程应该处理的代码,它没有继承Thread!!我们常说的UI线程,就是运行在上面的代码。
ApplicationThread跟Thread没多大关系,它主要是配合ApplicationThreadNative和ApplicationThreadProxy完成Binder进程间通信的。所以为啥元老Android发明者一开始要给定这个名字呢??
然后想讲其实整个ActivityThread的attach方法,里面涉及的代码,所有方法调用链,随便拿出一个来我感觉细聊的话都可以写篇文章。
很多细节比如intent的传递,ActivityThread时候时候会新建进程什么时候会寻找已有进程,activity启动是在具体什么时候读取的xml里面该activity标签的自定义属性的等等,都暂时忽略了。
//TODO
//给上面代码调用画个时序图。。。