盒子
盒子
文章目录
  1. Activity是如何创建的
  2. Activity的生命周期是如何被调用的

从源码看Activity生命周期

Activity是如何创建的

我们都知道在手机上点击应用的图标,系统会通过ActivityManagerService去启动它的主Activity,接下来我们就来一步步看看在它究竟是如何启动应用的。

首先手机开机的时候我们看到的界面其实是Launcher应用的主Activity,Launcher其实就是一个会被系统默认启动的安卓应用。在上面点击已装应用的图标,就会调用Actvity.startActivity去启动其他的应用。而Activity实际上是继承ContextWrapper的,所以调的是ContextWrapper.startActivity方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ContextWrapper extends Context {
...
Context mBase;
...
public ContextWrapper(Context base) {
mBase = base;
}
...
@Override
public void startActivity(Intent intent) {
mBase.startActivity(intent);
}
...
}

可以看到这里使用了委托的方式,实际上是调了mBase.startActivity。那这个mBase到底是什么呢?让我们来看看Context的继承关系图:

Context只有两个直接的子类,一个ContextImpl,一个ContextWrapper。ContextWrapper类如其名仅仅是一个包装的功能,它的成员变量mBase其实就是ContextImpl,所有实际的工作都是由ContextImpl去实现的。

于是我们就去看看ContextImpl.startActivity:

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
class ContextImpl extends Context {
...
@Override
public void startActivity(Intent intent) {
...
startActivity(intent, null);
}

@Override
public void startActivity(Intent intent, Bundle options) {
...
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity)null, intent, -1, options);
}
...
}

public final class ActivityThread {
...
Instrumentation mInstrumentation;
...
public Instrumentation getInstrumentation() {
return mInstrumentation;
}
...
}

好吧,这里又将锅甩给了Instrumentation。Instrumentation其实也是一个比较偏但是很有作用的东西(通过它我们能做到很多神奇的事情,例如Hook 应用入口 Activity),主要用于监控Activity,这里我就不详细讲了,感兴趣的同学可以直接去搜索一下。我们直接看启动activity相关的代码:

1
2
3
4
5
6
7
8
9
10
11
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
...
}

这里的ActivityManagerNative最后拿到的就是ActivtyManagerService的IBinder,所以最后会使用Binder机制调用系统端的ActivityManagerService去创建Activity。

但是我们知道ActivityManagerService和我们的应用是在两个进程的,如果在ActivityManagerService中创建了Activity的话我们的应用也是获取不了的。

其实ActivityManagerService主要功能不是创建Activity,而是管理Activity栈。它在创建新的Activity的时候还是会通过Binder机制调回应用进程的ActivityThread去处理。最后ActivityManagerService只保存Activity的token。由于中间代码过于曲折,我这里就不贴出来了.这里直接看ActivityThread的代码吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public final class ActivityThread {
final ArrayMap<IBinder, ActivityClientRecord> mActivities
= new ArrayMap<IBinder, ActivityClientRecord>();
...
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity a = performLaunchActivity(r, customIntent);
...
}
...
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
r.activity = activity;
...
mActivities.put(r.token, r);
}
}

可以看到这里也是用Instrumentation去创建Activity的,创建完之后就将它丢到一个Map里面。而Instrumentation.newActivity则很简单,通过反射去创建Activity:

1
2
3
4
5
6
7
8
9
public class Instrumentation {
...
public Activity newActivity(ClassLoader cl, String className, Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
...
}

总结下来,上面讲的的方法的调用时序图如下:

Activity的生命周期是如何被调用的

这里涉及到几个类:ActivityManagerService、ActivityStackSupervisor、ActivityStack、ActivityThread。

ActivityManagerService负责通过binder机制接收启动应用的请求,它内部有各个ActivityStackSupervisor成员变量,用于管理Activity栈:

1
2
3
4
5
6
7
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
...
/** Run all ActivityStacks through this */
ActivityStackSupervisor mStackSupervisor;
...
}

ActivityStackSupervisor管理用于Activity栈列表,它负责将Activity压入对应的Activity栈中:

1
2
3
4
5
6
public final class ActivityStackSupervisor {
...
/** All the non-launcher stacks */
private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
...
}

ActivityStack用于管理Activity的生命周期,例如在新Activity被压入的时候调用旧栈顶Activity的onPasuse和onStop还有新activity的onStart和onResume。

1
2
3
4
5
6
7
8
9
final class ActivityStack {
...
final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
...
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags);
...
}
...
}

ActivityStack并不会直接调用Activity的生命周期方法,而是通过ActivityThread间接调用。由于ActivityStack在系统进程中,而ActivityThread在应用进程中,所以通过Binder机制调用之后去到ActivityThread那里不是主线程,于是ActivityThread内部就使用了Handler机制同步到主线程中调用:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public final class ActivityThread {
...
public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges) {
queueOrSendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? 1 : 0),
configChanges);
}
...
private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
mH.sendMessage(msg);
}
}
...
private class H extends Handler {
...
public void handleMessage(Message msg) {
...
switch (msg.what) {
...
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
case RESUME_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
handleResumeActivity((IBinder)msg.obj, true,
msg.arg1 != 0, true);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
...
}
...
}
...
private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges) {
ActivityClientRecord r = mActivities.get(token);
...
}
}

这里需要提的一点是AcvitiyThread里面可能有不止一个activity。所以需要传一个token去指定调用哪个activity。handlePauseActivity方法最终会调用mInstrumentation.callActivityOnPause再调用到Activity.onPause。这里就不继续展示代码了。

总结一下,上面讲到的这些类之间的关系是这样的:

ActivityThread通过handler机制将activity的生命周期同步到主线程中调用: