Android Activity 生命周期函数是如何被调用的?

很多 Android 开发者都知道,App 里面线程间的通讯可以使用 Handler 来实现,而且 Android App 启动时,主线程默认启动一个 Looper

其原理简单来说,就是创建 Handler 的线程绑定了一个 Looper,Looper.loop() 方法是一个死循环,不断地从 MessageQueue 中取用消息,可以理解成堵塞了主线程。

Looper.java

public static void loop() {
    final Looper me = myLooper();
    final MessageQueue queue = me.mQueue;

    for (;;) {
        Message msg = queue.next(); // might block
        try {
            msg.target.dispatchMessage(msg);
            end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }
        msg.recycleUnchecked();
    }
}

虽然 Java 程序要持续运行,主线程是必定要堵塞,否则主线程执行完了,程序就关闭了。

但是,问题来了,堵塞了的主线程,为什么还有 OnCreate() 等生命周期函数的调用?或者说,堵塞了的主线程,是怎么执行其他逻辑的?

定义在 ActivityThread 的 Handler 子类

在 ActivityThread 中,定义了一个 Handler 子类 H ,这个子类的作用就是响应生命周期事件,将其他进程的执行结果放到主线程。

ActivityThread.java

private class H extends Handler {
    public static final int LAUNCH_ACTIVITY         = 100;
    public static final int PAUSE_ACTIVITY          = 101;
    public static final int PAUSE_ACTIVITY_FINISHING= 102;
    public static final int STOP_ACTIVITY_SHOW      = 103;
    public static final int STOP_ACTIVITY_HIDE      = 104;

    
    public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            case RELAUNCH_ACTIVITY: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                handleRelaunchActivity(r);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            case PAUSE_ACTIVITY: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                SomeArgs args = (SomeArgs) msg.obj;
                handlePauseActivity((IBinder) args.arg1, false,
                        (args.argi1 & USER_LEAVING) != 0, args.argi2,
                        (args.argi1 & DONT_REPORT) != 0, args.argi3);
                maybeSnapshot();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            case PAUSE_ACTIVITY_FINISHING: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                SomeArgs args = (SomeArgs) msg.obj;
                handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
                        args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            case STOP_ACTIVITY_SHOW: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
                SomeArgs args = (SomeArgs) msg.obj;
                handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
        }
        Object obj = msg.obj;
        if (obj instanceof SomeArgs) {
            ((SomeArgs) obj).recycle();
        }
        if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
    }
}

启动新 Activity 时

当我们使用 Activity 的 startActivity(Intent intent) 时,通过断点步进,可以一直追踪到 Instrumentation 的 execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) 方法。

Instrumentation.java

at android.app.Instrumentation.execStartActivity(Instrumentation.java:1615)
at android.app.Activity.startActivityForResult(Activity.java:4472)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67)
at android.app.Activity.startActivityForResult(Activity.java:4430)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:720)
at android.app.Activity.startActivity(Activity.java:4791)
at android.app.Activity.startActivity(Activity.java:4759)
at com.dujigui.playground.MainActivity.go(MainActivity.java:20)

关键代码在 execStartActivity方法最后

try {
    intent.migrateExtraStreamToClipData();
    intent.prepareToLeaveProcess(who);
    int result = ActivityManager.getService()
        .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) {
    throw new RuntimeException("Failure from system", e);
}

ActivityManager.getService() 获取到一个 IActivityManager,利用这个 IActivityManager 将控制权通过 RPC 交给系统,当系统准备就绪,需要调用 Activity 任何的生命周期函数时,发送一个 Message 到 ActivityThread 中的 H,H 通过 Message.what 即可知道如何处理此 Message。

换句话说,在 Android 中,生命周期函数是通过 Handler 被调用的。 ps: 文中展示代码有删减。