Activity 的启动流程初探

1、入口函数

运行一段 Java 函数的入口是 main 函数,Android 也有一个 main 函数,在 ActivityThread 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
// 初始化 Lopper
Looper.prepareMainLooper();
// 实例化一个 ActivityThread
ActivityThread thread = new ActivityThread();
// 通过 attach 发出创建 Application 的消息
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
// 创建主线程的 Handler
sMainThreadHandler = thread.getHandler();
}
// 使主线程进入无限循环状态
Looper.loop();
}

main 函数的主要作用:

  • 初始化 Looper,Handler
  • 使主线程进入等待接受 Message 的无限循环状态
  • 调用 attach 方法发出初始化 Application 的消息

    2、创建 Application(理解 IActivityManager 和 ApplicationThread)

1
2
3
4
5
6
private void attach(boolean system, long startSeq) {
// 获取 IActivityManager 实例
final IActivityManager mgr = ActivityManager.getService(); // 获取 ActivityManagerProxy 对象,它实现 IActivityManager 接口,ActivityManagerProxy 有个 mRemote 属性是一个 IBinder 对象(ActivityManagerService 可以和 ActivityManager 对象通信)
// 调用 IActivityManager 的 attachApplication 方法,传入 mAppThread 对象
mgr.attachApplication(mAppThread, startSeq);
}

那么 IActivityManager 是什么呢?

ActivityManager.getService 中又调用工 get 方法,方法中有这样的代码。
// 通过这个 Binder 可以和 ActivityManager 通信

1
2
3
// 通过这个 Binder 可以和 ActivityManager 通信
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);

可见 IActivityManager 是一个接口,调用 ActivityManager.getService 会返回一个代理类的实例 ActivityManagerProxy,它实现了 IActivityManager 接口

ActivityManagerProxy 的构造函数如下:

1
2
3
public ActivityManagerProxy(IBinder remote) {
mRemote = remote; // ActivityManagerService 对象
}

构造函数为 ActivityManagerProxy 初始化了 mRemote 变量 mRemote 是一个 Binder 对象,我们通过 IActivityManager 的身份去操作 ActivityManagerProxy,进而操作 这个 Binder 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
//先检查一下有没有
if (in != null) {
return in;
}
...
return new ActivityManagerProxy(obj);
//这个地方调用了构造函数
}

在 ActivityManager 的 getService 中又调用的 get 方法里会执行 IActivityManager 的 asInterface 方法,返回一个 ActivityMangerProxy 实例,这个我们上文也说了,这里调用了 ActivityManagerProxy 的构造函数传入的 IBinder 对象就是在 get 方法中获取的 IBinder 对象

再看 attachApplication 方法(应该在 ActivityManagerProxy 里)

1
2
3
4
5
6
public void attachApplication(IApplicationThread app){

// 调用 ActivityManagerService 的transact 方法
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
...
}

attachApplication 是 ActivityManagerProxy 中的方法,attachApplication 又调用了 ActivityManagerProxy 内部的 IBinder 对象(ActivityManagerService)的 transact 方法,这个方法运行在本地线程,这个方法传递了一 data 参数(data 封装了 IApplicationThread 对象)

IApplicationThread 是什么呢?

在 ActivityThread 中有一个 ApplicationThread 属性 mAppThread,它在 ActivityThread 中是这样定义的

1
final ApplicationThread mAppThread = new ApplicationThread();

而 ApplicationThread 是 ActivityThread 的一个内部类,

1
2
3
private class ApplicationThread extends IApplicationThread.Stub {
//...
}

继承自 IApplicationThread 类的 Stub(Binder 在服务端的实现类)
显然 ApplicationThread 也是一个 Binder,也是一个 IApplicationThread

那么 IApplicationThread 又是什么?

1
2
3
4
5
6
public interface IApplicationThread extends IInterface {
...
String descriptor = "android.app.IApplicationThread";
//留意下这个参数
...
}

IApplicationThread 继承了 IInterface 接口,它里面有一个 descriptor 参数,它是一个标示,用于查询。

总结:

  • 调用了 ActivityThread 的 attach 方法后,创建 IActivityManger 对象
  • IActivityManager 通过 ActivityManager.getService 获取

    • getService 中又调用了 IActivityManagerSingleton 的 get 方法
    • 在 get 方法里得到了 ActivtiyService 的对象(用于和 ActivityManager 通信),并将这个 Binder 对象(ActivityManagerProxy)返回。
  • IActivityManager(ActivityMangerProxy)调用 attachApplication 方法,传入了一个 ApplicationThread 对象

    • attachApplication 又调用它代理的对象(ActivityManagerService)的 transact 方法,传入封装好的 ApplicationThread 对象

    • ApplicationThread 是 ActivityThread 的内部类,继承自 IApplicationThread.Stub。(Application 也是个 Binder)


在 ActivityManagerService 中进行初始化 Application

1
2
3
4
5
6
7
private final boolean attachApplicationLocked(IApplicationThread thread
, int pid) {
...
//
thread.bindApplication(…………………);
...
}

ApplicationThread 以 IApplicationThread 的身份进入 ActivityManagerService 中,有调用了自己的 bindApplication 方法

1
2
3
4
5
6
7
8
9
10
11
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);

bindApplication 方法中最后会发送一条消息

1
sendMessage(H.BIND_APPLICATION, data);

H 是 主线程中的 Handler

1
class H extends Handler {…}

H 接收到 BIND_APPLICATION 的消息后,会执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void handleBindApplication(AppBindData data) {
...
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName())
.newInstance();
// 通过反射初始化一个 Instrumentation 仪表。后面会介绍。
...
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
// 通过 LoadedApp 命令创建 Application 实例
mInitialApplication = app;
...
mInstrumentation.callApplicationOnCreate(app);
// 让仪器调用Application的onCreate()方法
...
}

主要的任务:实例化一个 Instrumentation 对象;通过 data 创建一个 Application;调用 Instrumentation的 onCreate 方法

Instrumentation 啥玩意儿?

1
Instrumentation 会在应用程序的任何代码运行之前被实例化,它能够允许你监视应用程序和系统的所有交互。

看这类会发现, Application 的创建,Activity 的创建和生命周期都会经过这个类执行。

这么做的好处?

  • 当需要定义新的功能时,直接给 Instrumentation 添加抽象功能,调用就好了。不管怎么实现这些功能,都交给 Instrumentation 的实现对象就好。

最后调用 Instrumentation 的 callApplicationOnCreate 方法

1
2
3
4
mInstrumentation.callApplicationOnCreate(app);
public void callApplicationOnCreate(Application app) {
app.onCreate();
}

它只调用了 Application 的 onCreate 方法,这也是它为什么能起到监控的作用

然后看 data.info 的 Application 的创建过程 makeApplication(LoadedApk 就是 data.info)

1
2
3
4
5
6
7
8
9
10
11
12
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
// 用反射的技术
String appClass = mApplicationInfo.className;
...
// 注意 Context
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 通过 Instrumentation 创建 Application
app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext);
...
}

再把目光返回 Instrumentation 中的 newApplication

1
2
3
4
5
6
7
8
9
10
11
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
// getFactory 中获得 AppComponentFactory,在调用 AppComponentFactory 的 cl.loadClass(className).newInstance() 方法
// 通过反射获取创建一个 Application
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
// 给 Application 绑定 context
app.attach(context);
return app;
}

Application 终于创建出来了

总结:

  • 得到 ActivityManagerService 的代理后,调用代理类的 attachApplicationLocked 方法,内部传入了一个 ApplicationThread 对象

    • ApplicationThread 是 ActivityThread 的内部类,继承了 IApplicationThread.Stub(Binder 在服务端的实现类)
  • 然后又调用 ApplicationThread 本身的 bindApplication 方法

  • 方法的最后给 Handler H 发送了一条创建 Application 的消息

  • H 初始化了一个 Instrumentation 然后通过反射的技术创建了一个 Application


3、创建 Activity

  1. Application 创建成功后,系统根据 Manifest 中的配置文件发送一个 Intent 去匹配相应的 Activity。
  2. H 收到 LAUNCH_ACTIVITY,开会初始化 Activity
  3. 然后调用 ActivityThread 的 handleLaunchActivity 方法,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void handleLaunchActivity(ActivityClientRecord r
, Intent customIntent
, String reason) {
...
// Activity 的创建被封装到一个 方法里
Activity a = performLaunchActivity(r, customIntent);
...
if (a != null) {
...
(r.token
, false
, r.isForward
,!r.activity.mFinished && !r.startsNotResumed
, r.lastProcessedSeq, reason);
//Activity创建成功就往onResume()走了!
...
}
}

再看创建 Activity 的过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
private Activity performLaunchActivity(ActivityClientRecord r
, Intent customIntent) {
...
// 通过仪表盘来创建 Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
// 获取 Application
Application app = r.packageInfo.makeApplication(false
, mInstrumentation);
...
activity.attach(appContext
, this
, getInstrumentation()
, r.token
,.ident
, app
, r.intent
, r.activityInfo
, title
, r.parent
, r.embeddedID
, r.lastNonConfigurationInstances
, config
,r.referrer
, r.voiceInteractor
, window);
...
// 根据是否可持久化选择 onCreate 启动
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(
activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}

看第一个方法 Instrumentation 的 newActivity

1
2
3
4
5
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException,ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null ? intent.getComponent().getPackageName() : null;
// 反射创建一个 Activity
return getFactory(pkg).instantiateActivity(cl, className, intent);
}

根据是否可以持久化选择 onCreate 启动

1
2
3
4
5
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}

对应的 performCreate 方法为

1
2
3
4
5
6
7
8
9
10
11
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}

performCreate 方法中会调用 onCreate

1
2
3
4
5
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}

总结:

  • Application 创建完成后,根据 Manifest 文件发送 Intent 创建 MainActivity

  • H 收到创建 Activity 的消息后,调用 ActivityThread 的 handleLaunchActivity 方法创建 Activity

  • handleLaunchActivity 又会调用 performLaunchActivity

  • performLaunchActivity 通过仪表板来创建新的 Activity(用反射)

  • 然后调用 Instrumentation 的 callActivityOnCreate() 去执行 Activity 的 onCreate 方法

  • Activity 创建成功后,H 又调用 handleResumeActivity