最近由于工作需要,需要深入了解AMS的内部实现。说老实话,虽然已经经过了几轮重构,AMS的代码还是又臭又长。。。
万事开头难,先找个入口开始看吧。当从Launcher界面点击启动一个app时,会启动一个新的activity。所以就从startActivity()看起,研究一下activity启动的整个流程。
虽然代码很长,大体上还是有个一个脉络的,参见下图:
这样是不是感觉清楚很多?基本上分为下面这些步骤:
- 创建相关的数据结构并建立联系(ActivityRecord, ActivityStack, TaskRecord等等)
- Pause前一个activity(这里指的就是Launcher)
- 创建新进程,启动新的ActivityThread
- 传递binder通信对象,创建Activity并调用其onCreate()方法
下面详细分析一下相关代码(基于android 5.1):
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);
}
}
Activity调用Instrumentation去启动新的activity:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
... ...
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
... ...
}
Instrumentation通过binder将请求发送到远端的ActivityManagerService。ActivityManagerNative.getDefault()返回的是一个IActivityManager接口,后面会详细讲解这个接口是怎么和远端联系起来的。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Fragment target,
Intent intent, int requestCode, Bundle options) {
... ...
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mWho : null,
requestCode, 0, null, options);
... ...
}
static public IActivityManager getDefault() {
return gDefault.get();
}
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);
return am;
}
}
先看一下Java Binder的一般结构:
左半边是server端的具体实现,右半边是client端使用的代理。这样一来就很清楚了,IActivityManager必定有一个ActivityManagerProxy的代理类,里面包含了一个BinderProxy对象来和远端通信。远端也必定有一个ActivityManagerNative的类负责响应binder请求,同时有一个子类来完成具体的业务逻辑,这个类就是ActivityManagerService。具体类图如下:
这里谈到了ActivityManagerService,那我们就先来看一下它是怎么启动的。
ActivityManagerService是在SystemServer里通过SystemServiceManager的startService()方法启动的,传入的参数是一个叫Lifecycle的内部类。该方法会利用反射的方式,根据类名获取其构造函数,创建对象实例,最后调用service的onStart()方法。
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
public <T extends SystemService> T startService(Class<T> serviceClass) {
... ...
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
... ...
// Register it
mServices.add(service);
// Start it
service.onStart();
... ...
}
看一眼Lifecycle类,该类继承自SystemService,构造函数里会创建ActivityManagerService实例,onStart()里会调用ActivityManagerService的start()方法。
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start();
}
public ActivityManagerService getService() {
return mService;
}
}
仅仅启动ActivityManagerService是不够的,外面的人怎么来访问它呢?显然需要把ActivityManagerService注册到ServiceManager里,这一步也是在