Activity源码分析

Activity 源码解析

Activity是Android里非常重要的一个组件。东西非常多,如果本文有没有覆盖到,但你又觉得非常重要的部分,欢迎给我反馈。如果你发现了任何错误也欢迎给我反馈。(Email:[email protected]

以下全部基于Android 8.0 Api26的源码分析。不同版本可能稍有不同。但整个基本原理其实是完全一样的。
既然是源码分析,所以这里不会去做功能分析,比如Activity都有什么功能,startActivity怎么调用,怎么给Activity添加专场动画等,这里会着重分析Activity从创建到结束,都经过了哪些过程,这些过程代码都在什么位置,Activity是在哪里new出来的,生命周期为什么能被回调等等这些,本文会跟随着Android系统的代码执行顺序,一步步从Activity被创建分析到Activity被销毁。大致会从以下几个部分来介绍,有一定的阅读门槛:

  • Android消息机制
  • ActivityThread介绍
  • Activity如何收到消息
  • Activity的生命周期事件
  • Activity结束
  • 总结

1. 简介

Activity是Android的四大组件之一,光注释都五六百行。大致从注释能看到Activity本身是为UI服务的,介绍了生命周期和一些常用功能。更详细的还需要从源码层面分析。

2. 源码分析

1.Android消息机制

除了类似单片机这种特殊的操作系统,大部分操作系统都会有消息机制。消息机制把软件需要执行的代码都包装成消息。有了消息机制可以很方便的让软件对外界操作进行实时响应。一个RecyclerView,你上滑一下,RecyclerView滑动还没有结束你这时候可以按住RecyclerView,RecyclerView会实时响应你的操作让滑动立刻停止。怎么做到的?其实就是消息机制。RecyclerView的滑动被分割成了若干个消息,每个消息都移动一小段距离,这时候你突然按住RecyclerView,你的操作会被立即插入到消息循环,这时候不再执行移动的操作,而是响应你按住这个操作,让RecyclerView立刻停止。用户看到的效果就是App实时响应了用户的请求,没有因为App当前正在滑动RecyclerView而用户等待动画结束。

在Android中实现消息机制的就是Handler、Message、MessageQueue、Looper这四兄弟。任何操作都被封装成Message被添加到MessageQueue中,Looper负责消息的循环,拿到消息后交给Handler来处理。
这里之所以要简单介绍消息机制,主要就是Activity的各种事件本质来源其实都是Handler消息。知道消息机制,接下来就会很容易理解Activity的一系列事件回调。

2.ActivityThread介绍

Java可以很方便的随时Dump当前的方法栈,可以看到当前代码是经过了怎样的方法栈被调到的。

      at android.app.Activity.performCreate(Activity.java:6975)
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2784)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2906)
      at android.app.ActivityThread.-wrap11(ActivityThread.java:-1)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1605)
      at android.os.Handler.dispatchMessage(Handler.java:105)
      at android.os.Looper.loop(Looper.java:172)
      at android.app.ActivityThread.main(ActivityThread.java:6637)
      at java.lang.reflect.Method.invoke(Method.java:-1)
      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

在任意一个Activity的onCreate加个断点,可以得到以上方法栈数据。或者每当App崩溃的时候也会有类似数据被输出到Log,再或者也可以通过

        Thread.currentThread().getStackTrace();

得到方法栈自己输出到Logcat。除了关注自己代码部分,可能很少会有人去关注下面这些方法。下面这些方法你有看到Looper.loop吗?这不是我们的消息循环吗?loop是被谁调用的?ActivityThread.main。ActivityThread的main方法就是Android App的入口代码(这个入口是被ActivityManagerService定义的,那可以在ActivityManagerService中找到相关代码,这里不做详细介绍)。ActivityThread源码包含在SDK中(如果你双击Shift输入ActivityThread IDE没有找到这个类的话,你可以先找到Activity类,然后在Activity源码中find查找ActivityThread,然后通过快捷键跟进ActivityThread源码)。
定位到main方法:

public class ActivityThread{

    ...

    private void attach(boolean system) {
        if (!system) {
            ...
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...
        }
    }

    ...

    public static void main(String[] args) {
        ......
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}

基本上做了两件事,初始化ActivityThread(注意有个mgr.attachApplication(mAppThread)注册mAppThread),然后在main方法最后进入了Looper.loop的消息循环,因为这个循环是不会结束的,所以最后一个异常正常情况下是不会被执行到的。当然你可以通过

        Looper.getMainLooper().quit();

强行让主线程消息循环结束。

看到这里我们应该明白,在App初始化完成后,执行的代码都会进入到Looper中执行,所以就很容易理解,其实我们的Activity创建,Activity生命周期回调也将是Handler消息的形式。

在ActivityThread类中有个内部类H,继承自Handler。H类定义了很多类型的int,看名字其实很容易跟生命周期回调对应起来。

3.Activity如何收到消息

前面我们知道Looper.loop之后,App要想执行代码,肯定是通过HandlerMessage的形式。那么Activity在创建前一定是收到了一个HandlerMessage。找到处理Message的H类,里面有个LAUNCH_ACTIVITY。

private class H extends Handler {
    public static final int LAUNCH_ACTIVITY         = 100;
    ...
    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;
            ...
        }
        ...
    }
}

在handleMessage时候通过handleLaunchActivity来处理LAUNCH_ACTIVITY消息。
在分析处理部分的代码前,我们回过来想下LAUNCH_ACTIVITY消息是被谁发出的呢?find搜下。

class ActivityThread{
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        ...
        @Override
        public final void scheduleLaunchActivity(...){
            ...
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
        ...
    }
    ...
}

保留关键代码就是上面的结构。到这里创建Activity的代码,其实都涉及到了。为了更清楚的理解,我们再把代码顺序梳理下,就是下面的代码从上到下。我用“>数字”标出了代码执行顺序。顺着数字顺序可以很清晰的理解这个过程。

public class ActivityThread{

    ...
    // >1
    // App入口
    public static void main(String[] args) {
        ......
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        // >2
        // 初始化一些必要数据
        thread.attach(false);
        // >5
        // 启动消息循环
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

    ...
    // >3
    private void attach(boolean system) {
        if (!system) {
            ...
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                // >4
                // 注册binder到远端ActivityManagerService
                // 注册完成后mAppThread就可以接收ActivityMangerService跨进程发过来的消息了。
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...
        }
    }

    ...

    private class ApplicationThread extends IApplicationThread.Stub {
        ...
        // >6
        // 远端ActivityManagerService通过Binder跨进程通信,
        // 调到这个方法,当前在App的Binder线程。
        @Override
        public final void scheduleLaunchActivity(...){
            ...
            // >7
            // 由于此时在Binder线程,所以不能直接调用handleLaunchActivity方法。
            // 需要通过Handler跨线程通信给主线程发LAUNCH_ACTIVITY消息。
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
        ...
    }
    ...

    private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;

        ...
        // >8
        // 主线程收到LAUNCH_ACTIVITY消息。
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    // 处理LAUNCH_ACTIVITY消息
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    // >9
                    // 打开Activity
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                ...
            }
            ...
        }
        ...
    }
}

LAUNCH_ACTIVITY事件从scheduleLaunchActivity发出。那scheduleLaunchActivity被谁调用?还记得前面初始化ActivityThread我说的(注意有个setApplicationObject注册mAppThread)吗?ApplicationThread继承自IApplicationThread.Stub,看到Stub是不是觉得很熟悉?就是Binder跨进程通信。
在Looper进入loop循环前,调用了ActivityThread.attach方法,在attach中将ApplicationThread绑定到了系统的ActivityManagerService进程。此时只要ActivityManagerSercice通过跨进程通信给App发LAUNCH_ACTIVITY消息,那么ApplicationThread的scheduleLaunchActivity将收到LAUNCH_ACTIVITY消息,但是因为此时ApplicationThread是在Binder线程,所以此时将通过Handler跨线程给主线程发LAUNCH_ACTIVITY,主线程的H类的handlerMessage收到LAUNCH_ACTIVITY,然后调用handleLaunchActivity(这里梳理了下系统是如何收到打开Activity消息的,后面还会把怎么发出消息即startActivity也给分析下)。

3.Activity的生命周期事件

把App如何接收LAUNCH_ACTIVITY消息梳理完了,下面就要开始Activity是怎么被new的,以及Activity是如何收到各种声明周期事件的。还是老样子,我把Activity创建和生命周期相关关键代码贴出来,并用“>数字”来标注执行顺序。

    // >1
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();
        // 创建Activity以及处理生命周期
        // >2
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            ...
            // >12
            // onResume
            handleResumeActivity(...);
            ...
            }
        } else {
            ...
        }
    }

    // >3
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // >4
            // 创建Activity实例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } catch (Exception e) {
            ...
        }
        try {
            ...
            activity.attach(...);
            ...
            // >7
            // onCreate
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ...
            // >8
            // onStart
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            // >9
            // onRestore
            if (!r.activity.mFinished) {
                if (r.isPersistable()) {
                    if (r.state != null || r.persistentState != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            // >10
            // onPostCreate
            if (!r.activity.mFinished) {
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                } else {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPostCreate()");
                }
            }
            r.paused = true;
            // >11
            // 持有Activity实例的r被添加到mActivities中。
            mActivities.put(r.token, r);
            ...
        } catch (Exception e) {
            ...
        }
        ...
    }
    // >13
    final void handleResumeActivity(...) {
        ...
        // >14
        // onResume
        r = performResumeActivity(token, clearHide, reason);
        if (r != null) {
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                // 不可见,后面会通过activity.makeVisible()恢复可见
                decor.setVisibility(View.INVISIBLE);
                ...
                if (a.mVisibleFromClient) {
                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
                        // >17
                        // 被添加到WindowManager
                        wm.addView(decor, l);
                    } else {
                        ...
                    }
                }
                ...
                        // 恢复Activity可见
                        r.activity.makeVisible();
                ...
            ...
            }
        }
    }
    ...
    // >15
    // onResume
    public final ActivityClientRecord performResumeActivity(...) {
        ...
        if (r != null && !r.activity.mFinished) {
            ...
            try {
                ...
                // >16
                // onResume
                r.activity.performResume();
                ...
            } catch (Exception e) {
                ...
            }
    }
public class Instrumentation {
    ...
    // >5
    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        // >6
        // 通过反射创建Activity实例
        return (Activity)cl.loadClass(className).newInstance();
    }
    ...
}

我已经用“>数字”把主要的事件执行顺序回调贴出来了。按照顺序可以很清晰的看到一个Activity是怎么被创建出来的,以及创建出来后比如onCreate、onStart等各个生命周期是如何收到回调事件的。收到LAUNCH_ACTIVITY消息后,ActivityManagerService不需要再发送RESUME_ACTIVITY消息,LAUNCH_ACTIVITY处理过程会直接处理掉onStart,onResume。
那假如我此时按下Home键后,App要收到onPause消息,我们来分析下这个过程。
按下Home后,ActivityManagerService将通过跨进程通信给App发送PAUSE_ACTIVITY的消息。

public final class ActivityThread {
    private class ApplicationThread extends IApplicationThread.Stub {
        ...
        // >1
        // 当前在Binder线程收到ActivityManagerService跨进程通信
        public final void schedulePauseActivity(...) {
            ...
            // >2
            // 此时在Binder,给主线程发PAUSE_ACTIVITY的消息
            // 如果是finished就发送PAUSE_ACTIVITY_FINISHING消息。
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                    configChanges,
                    seq);
        }
        ...
    }
 
    private class H extends Handler {
        // >3
        // 此时进入主线程
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case PAUSE_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    SomeArgs args = (SomeArgs) msg.obj;
                    // >4
                    // onPause∏
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
            }
        }
    }
    // >5
    private void handlePauseActivity(...) {
        ...
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                // >6
                // 见过这个生命周期吗?
                performUserLeavingActivity(r);
            }
            // >8
            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
            ...
        }
    }

    // >7
    final void performUserLeavingActivity(ActivityClientRecord r) {
        mInstrumentation.callActivityOnUserLeaving(r.activity);
    }

    // >9
    final Bundle performPauseActivity(IBinder token, boolean finished,
            boolean saveState, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        // >10
        // 重载performPauseActivity
        return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
    }

    // >11
    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState, String reason) {
        ...
        // >12
        // 回调onSaveInstanceState
        // Next have the activity save its current state and managed dialogs...
        if (!r.activity.mFinished && saveState) {
            callCallActivityOnSaveInstanceState(r);
        }

        // >13
        performPauseActivityIfNeeded(r, reason);

        ...
        // >16
        return !r.activity.mFinished && saveState ? r.state : null;
    }

    // >14
    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        ...

        try {
            ...
            // >15
            // 回调onPause
            mInstrumentation.callActivityOnPause(r.activity);
            ...
        } catch (...) {
            ...
        }
        r.paused = true;
    }
}

好了,onPause结束。过程很简单,顺便还能学到一个回调performUserLeavingActivity。同样的onResume过程跟onPause过程基本差不多,这里就不再啰嗦了。
到了这里其实你应该也就非常清楚了所有生命周期回调的先后顺序,以及每个生命周期具体是怎么回调到Activity的。那么生命周期的介绍就算告一个段落了。

4.Activity的结束

这里再说下mActivies。

public final class ActivityThread {
    ...
    // 在低版本上这里是用的HashMap
    final ArrayMap mActivities = new ArrayMap<>();
    ...
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        mActivities.put(r.token, r);
        ...
    }
    ...
}

还记得前面在LaunchActivity的时候把持有Activity实例的ActivityClientRecord r被put到mActivities吗?Java不需要自己手动处理对象释放,Java会通过自己的GC来释放。那么Activity对象在创建后肯定需要一个对象来持有它,否则Activity实例在GC时候就会被销毁了。那么谁来持有Activity?就是这里到mActivities。所有Activity被创建后都会被添加进来,当然与之对应的就会在onDestory的时候从mActivities中移除。你可以尝试用上面分析的过程去找下什么时候被移除的。

3. 总结

Activity的东西非常多,但只要理解了其中的规律,就会很容易举一反三。如果你看明白了这整个过程,就可以很轻松的通过H类定义的msg.what,找到App都能接受到多少种不同类型的系统回调。这些回调有Activity的,也有Service的,也有Application的等等。同样的方法你可以很容易分析Service的消息处理过程,大家都在说Service onStartCommand是发生在主线程,那么为什么是主线程?同样的思路,你可以非常容易弄明白这个过程。

你可能感兴趣的:(Activity源码分析)