Activity启动流程分析


App启动流程分析中已经分析过大部分的流程了,但是对于Activity的启动流程并没有详细的说明,这里讲一下.

在分析源码之前,先想一下大概有哪些疑问:

  • Activity是如何加载的?
  • Activity为什么必须在Manifest文件中注册?
  • Activity的本质是什么,可以不需要Activity实现Android APP吗?
  • Activity的生命周期是如何调度的?
  • Activity的启动模式的原理

源码中常见的类

  • ActivityRecord

    表示一个Activity,与Activity是一一对应的关系

  • ActivityStack

    即Activity栈,管理Activity的状态

  • RootActivityContainer

    一个暂时分离出来的类,主要就是一些不应该放到ActivityStackSuperVisor中的功能,可能后面会合并到RootWindowContainer中

Binder调用前

由于之前分析过一些代码的调用流程,这里从ActivityStackSupervisor#startSpecificActivityLocked()开始:

    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {

        if (wpc != null && wpc.hasThread()) {
            try {
                // 进程已经准备好,执行这个过程
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
            knownToBeDead = true;
        }

        // 还未创建进程,先创建进程
        try {
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

之前说过,创建APP进程的时候走的是下面那个逻辑,这里启动Activity的时候看realStartActivityLocked方法:

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        final TaskRecord task = r.getTaskRecord();
        final ActivityStack stack = task.getStack();
        beginDeferResume();

        try {
            r.startFreezingScreenLocked(proc, 0);
            // schedule launch ticks to collect information about slow apps.
            r.startLaunchTickingLocked();
            r.setProcess(proc);
            proc.addActivityIfNeeded(r);

            try {
                // 关键:创建Activity启动事务
                final  clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                // 将intent信息打包到LaunchActivityItem中去
                // LaunchActivityItem表示启动Activity的请求,是ClientTransactionItem的子类
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));

                // Activity应该到达的生命周期状态
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // 关键:执行请求,Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            }
        } finally {
            endDeferResume();
        }
        return true;
    }

看一下调度事务的代码:

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            transaction.recycle();
        }
    }

    public void schedule() throws RemoteException {
        // 这里的mClient就是IApplicationThread,会通过Binder调用到ApplicationThread
        mClient.scheduleTransaction(this);
    }    

ActivityThread.ApplicationThread中的调度过程

现在进入了ApplicationThread中:

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

ActivityThead实现了ClientTransactionHandler:

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        // 预先执行一些逻辑
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i < size; ++i) {
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }

这里的mActivityCallback即上面添加的LaunchActivityItem,因此会先执行它的preExecute方法:

    @Override
    public void preExecute(ClientTransactionHandler client, IBinder token) {
        client.countLaunchingActivities(1);
        client.updateProcessState(mProcState, false);
        client.updatePendingConfiguration(mCurConfig);
    }

这里就是更新下信息,没什么大不了的,看来还是分析下面的这一句比较重要:

 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);

ActivityThread.H中有:

                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    break;

继续看:

    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        // 执行callback
        executeCallbacks(transaction);
        // 过渡到最终状态,即Resumed状态
        executeLifecycleState(transaction);
        mPendingActions.clear();
    }

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();  
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            // 执行callback
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
        }
    }

    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

这下思路清晰了:

  1. 先执行LaunchActivityItem中的executepostExecute方法
  2. 再执行ResumeActivityItem中的executepostExecute方法

Launch

看下LaunchActivityItem的指令:

    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        // ActivityClientRecord用于记录真实的Activity实例
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken);
        // 调用ActivityThread的handleLaunchActivity方法        
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

这下进入到了ActivityThread中的handleLaunchActivity方法了:

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {

        // Initialize before creating the activity
        // 看看是否支持硬件加速,支持的话就预加载
        if (!ThreadedRenderer.sRendererDisabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        // 初始化WindowManagerService服务
        WindowManagerGlobal.initialize();

        // Hint the GraphicsEnvironment that an activity is launching on the process.
        GraphicsEnvironment.hintActivityLaunch();
        // 启动Activity
        final Activity a = performLaunchActivity(r, customIntent);

        return a;
    }

这下进入了启动Activity的核心实现代码了:

    /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        // 目标Activity的ComponnetName
        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        // 为Activity创建Context
        ContextImpl appContext = createBaseContextForActivity(r);
        // 目标Activity
        Activity activity = null;
        try {
            //重头戏,创建目标Activity
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                appContext.setOuterContext(activity);
                // 执行Activity的attach方法
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    // 这是主题
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                // 执行Activity的onCreate()回调
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
            }
            r.setState(ON_CREATE);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

这里主要干了下面这几件事:

  1. 为目标Activity创建Context
  2. 使用ClassLoader加载Activity类并实例化
  3. 使用ClassLoader加载Application并实例化,调用attach()和onCreate()方法
  4. 执行Activity的attach() 方法并为Activity设置主题
  5. 使用Instrumentation执行Activity的onCreate()回调

Application和Activity代码的加载和实例化入口都在Instrumentation中:

    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        String pkg = intent != null && intent.getComponent() != null
                ? intent.getComponent().getPackageName() : null;
        return getFactory(pkg).instantiateActivity(cl, className, intent);
    }

    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    }    

实例化其实都是反射调用:

    public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
            @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Application) cl.loadClass(className).newInstance();
    }

    public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
            @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Activity) cl.loadClass(className).newInstance();
    }    

Activity.onCreate()

至于Activity的onCreate()回调,也在Instrumentation中进行:

    public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {

        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        mFragments.dispatchActivityCreated();
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
        dispatchActivityPostCreated(icicle);
    }

到这里onCreate()回调就被调用了.

再来看下onResume()回调的调用吧

Activity.onResume()

还是回到之前的ResumeActivityItem中:

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        // 调用ActivityThread的handleResumeActivity方法
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        try {
            // TODO(lifecycler): Use interface callback instead of AMS.
            ActivityTaskManager.getService().activityResumed(token);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

还是Binder调用到ActivityThread中:

    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        // 执行onResume()
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        Looper.myQueue().addIdleHandler(new Idler());
    }

    public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
            String reason) {
        final ActivityClientRecord r = mActivities.get(token);
        try {
            // 执行onResume
            r.activity.performResume(r.startsNotResumed, reason);

            r.state = null;
            r.persistentState = null;
            r.setState(ON_RESUME);
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException("Unable to resume activity "
                        + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
            }
        }
        return r;
    }

到这里Activity启动流程就分析完了.

总结

  1. 基于ClientTransaction的消息传递机制,通过Binder调用到ActivityThread中的方法
  2. ActivityThread中会使用InstrumentationHandler去执行各种逻辑
  3. LoadedApkInstrumentaion负责Application的创建和实例化
  4. Instrumentation负责Activity的创建和实例化
  5. Application和Activity的创建和实例化其实都是利用的Classloader和反射机制
  6. 四大组件的实例化代码都在AppComponentFactory

文章作者: 姜康
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 姜康 !
评论
 上一篇
Android Service启动流程分析 Android Service启动流程分析
之前写过App和Activity的启动流程分析: App启动流程分析 Activity启动流程分析 现在梳理下Service的启动流程吧 基于Android 10的源码分析 ContextWrapper.startService()
2020-08-23
下一篇 
文件压缩格式 文件压缩格式
zlibzlib 是一个压缩,解压数据的工具库,只是单纯的数据压缩,不管数据来源。 gzipgzip 只能压缩单个文件 tartar 压缩多个文件,通常与gzip配合使用。比如linux上常见的. tar. gz zipzip 用于压缩多个
2020-08-22
  目录