Activity启动流程(二)

2023-05-16

  • 应用进程绑定到AMS
  • AMS发送启动Activity的请求
  • ActivityThread的Handler处理启动Activity的请求

一、应用进程绑定到AMS

1. 时序图

\[外链图片转存失败(img-DlmoMg47-1566527233633)(F:\md\开发艺术探索\images\启动流程\应用进程绑定到AMS.png)\]

 

2. 详细过程

在前面一篇我们知道当Zygote进程孵化出应用进程后会执行ActivityThread的main方法,所以我们先看看main方法里的代码。

frameworks/base/core/java/android/app/ActivityThread.java

    public static void main(String[] args) {
        ....
		//创建主线程的Looper以及MessageQueue
        Looper.prepareMainLooper();
        ...
        //AMS绑定ApplicationThread对象,即应用进程绑定到AMS
        thread.attach(false, startSeq);
		//开启主线程的消息循环
        Looper.loop();
        ...
    }
复制代码

在这里我们就不再详细分析prepareMainLooper和loop方法,其主要功能就是准备好主线程的Looper以及消息队列,最后再开启主线程的消息循环。如果不懂的可以看看前面的博客Handler机制中对这两个方法的分析,在这里我们将重点分析attach这个方法。

frameworks/base/core/java/android/app/ActivityThread.java

    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
				//AMS绑定ApplicationThread对象
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            //垃圾回收观察者
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } 
        ...
    }
复制代码

可以看到由于在ActivityThread的attach中我们传入的是false,故在attach方法中将执行!system里的代码,通过调用AMS的attachApplication来将ActivityThread中的内部类ApplicationThread对象绑定至AMS,这样AMS就可以通过这个代理对象 来控制应用进程。接着为这个进程添加垃圾回收观察者,每当系统触发垃圾回收的时候就在run方法中计算应用使用了多大的内存,如果超过总量的3/4就尝试释放内存。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }


    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
			....
			    //将应用进程的ApplicationThread对象绑定到AMS,即AMS获得ApplicationThread的代理对象
                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);
          

        boolean badApp = false;
        boolean didSomething = false;
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
				//启动Activity
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        .....
    }

复制代码

在AMS的attachApplication方法中调用了attachApplicationLocked进行绑定,从上面代码可以发现attachApplicationLocked中有两个重要的方法:thread.bindApplication和mStackSupervisor.attachApplicationLocked(app)。thread.bindApplication中的thread其实就是ActivityThread里ApplicationThread对象在AMS的代理对象,故此方法将最终调用ApplicationThread的bindApplication方法。而mStackSupervisor.attachApplicationLocked(app)主要是AMS启动Activity的作用(在下列AMS发送启动Activity的请求会分析到)。在这里我们先看看ApplicationThread的bindApplication方法。

frameworks/base/core/java/android/app/ActivityThread.ApplicationThread

       public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, boolean autofillCompatibilityEnabled) {

          	....
			//向H发送绑定ApplicationThread对象的消息
            sendMessage(H.BIND_APPLICATION, data);
        }

    void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        ...
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

复制代码

可以发现上面其实就是Handler机制的应用,mH其实就是H类型的,所以bindApplication主要就是向ActivityThread的Handler,即H发送绑定的消息。

frameworks/base/core/java/android/app/ActivityThread.H

	//线程所需要的Handler,内部定义了一组消息类型,主要包括四大组件的启动和停止过程
    class H extends Handler {
        public static final int BIND_APPLICATION        = 110;
        ...
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                ...
        }
    }

复制代码

这个H其实就是当前线程,也可以说是主线程ActivityThread的Handler,内部定义了一组消息类型,包括了四大组件的启动和停止过程。通过Handler机制我们知道在H的handleMessage中会处理发送给H的消息,在这里将调用handleBindApplication方法。

frameworks/base/core/java/android/app/ActivityThread

    @UnsupportedAppUsage
    private void handleBindApplication(AppBindData data) {

        ....
        final InstrumentationInfo ii;
        if (data.instrumentationName != null) {
            try {
                ii = new ApplicationPackageManager(null, getPackageManager())
                        .getInstrumentationInfo(data.instrumentationName, 0);
            } 
            ...
        } else {
            ii = null;
        }
        ....
        // Continue loading instrumentation.
        if (ii != null) {
            .....
        } else {
            mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);
        }
        ....
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
            try {
                //调用Application的onCreate的方法
                //故Application的onCreate比ActivityThread的main方法慢执行
                //但是会比所有该应用Activity的生命周期先调用,因为此时的Activity还没启动
                mInstrumentation.callApplicationOnCreate(app);
            }
            ...
        } 
    }

二、AMS发送启动Activity的请求

应用进程绑定后,随之就得启动Activity,那么得向谁发送启动Activity得到请求呢?显而易见,当然是向主线程即ActivityThread发送启动Activity的请求。下面就让我们一探究竟!

1. 时序图

\[外链图片转存失败(img-UaWral2q-1566527233635)(F:\md\开发艺术探索\images\启动流程\AMS发送启动Activity的请求.png)\]

2. 详细过程

现在当前进程已经绑定到了AMS,绑定后呢?回忆一下,上面对AMS的attachApplicationLocked方法分析时,重点提到了两个方法,其中ApplicationThread的bindApplication方法我们分析应用进程是如何绑定到AMS的,没错!另外一个方法mStackSupervisor.attachApplicationLocked(app)就是用来启动Activity的,现在让我们来看看。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ...
            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                ....
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
						    //真正启动Activity,也是普通Activity的启动过程
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                             ...
                        }
                    }
                }
            }
        }
        return didSomething;
    }
复制代码

attachApplicationLocked会调用realStartActivityLocked方法,如下。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
                .....
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
			    //添加callback,首先会执行callback中的方法
                 //此时的ActivityLifecycleItem为LaunchActivityItem
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

                //判断此时的生命周期是resume还是pause
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                //设置当前的生命周期
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // mService为AMS对象,getLifecycleManager得到ClientLifecycleManager
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        	    ......
            } 
			....
        return true;
    }
复制代码

在realStartActivityLocked方法中为ClientTransaction对象添加LaunchActivityItem的callback,然后设置当前的生命周期状态,由于我们是根Activity的启动,很显然这里的生命周期为ResumeActivityItem,最后调用ClientLifecycleManager.scheduleTransaction方法执行。我们继续追踪下去!

frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java

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

从上面代码中可以看出,由于transaction为ClientTransaction类型,故接下去将执行ClientTransaction的schedule方法

frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java

    public void schedule() throws RemoteException {
        //1.mClient是IApplicationThread类型,
        //2.ActivityThread的内部类ApplicationThread派生这个接口类并实现了对应的方法
        //3.ActivityThread实际调用的是他父类ClientTransactionHandler的scheduleTransaction方法。
        mClient.scheduleTransaction(this);
    }
复制代码

mClient是IApplicationThread类型,通过名字和阅读源码我们可以知道ApplicationThread会实现该类型,所以这里调用的应该是ApplicationThread的scheduleTransaction方法,我们知道ApplicationThread是ActivityThread的内部类,所以通过阅读ActivityThread源码你会发现在这个类中并没有实现scheduleTransaction这个方法,难道分析错了????

聪明的你应该想到了,既然在当前类找不到这个方法,只能去找父类寻求帮助了,果然姜还是老的辣,在ActivityThread的父类ClientTransactionHandler中我们找到了这个scheduleTransaction方法。如下

frameworks\base\core\java\android\app\ClientTransactionHandler.java

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    abstract void sendMessage(int what, Object obj);
复制代码

看到这是不是突然觉得很熟悉,不急,我们一步一步来分析!在这个方法中会调用sendMessage方法,而在ClientTransactionHandler类中该sendMessage方法为抽象方法,其具体实现在子类ActivityThread中,如下

frameworks/base/services/core/java/com/android/server/am/ActivityThread.java

    void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }
复制代码

上面的代码很容易理解,在ActivityThread的sendMessage中会把启动Activity的消息发送给mH,而mH为H类型,其实就是ActivityThread的Handler。到这里AMS就将启动Activity的请求发送给了ActivityThread的Handler。

三、ActivityThread的Handler处理启动Activity的请求

1. 时序图

\[外链图片转存失败(img-Ohks0kHI-1566527233637)(F:\md\开发艺术探索\images\启动流程\ActivityThread的Handler处理启动Activity的请求.png)\]

2. 详细过程

既然发送了启动Activity的消息,那么就得ActivityThread当然得处理这个消息,我们知道Handler机制,如果是通过sendMessage的方法发送消息的话,应该是在Handler的handleMessage处理消息,在这里也同样如此,ActivityThread的Handler就是H,让我们来看看H的handleMessage,看看是否能找到EXECUTE_TRANSACTION消息的处理.

frameworks/base/core/java/android/app/ActivityThread.H

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                ......
				//处理事务,处理活动的启动,生命周期的转化等	
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
					//切换Activity的状态
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;
                ....
            }
            ...
        }
复制代码

果真如此,我们H接受到AMS发来的EXECUTE_TRANSACTION消息后,将调用TransactionExecutor.execute方法来切换Activity状态。

frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java

    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
        //先执行callbacks,当根活动首次启动时会有callback,callback会执行onCreate方法
        //其它活动切换状态时没有callback
        executeCallbacks(transaction);
        //改变活动的生命周期状态
        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }
复制代码

在execute方法中重点关注两个方法:executeCallbacks,由于我们现在分析的是根Activity的启动流程,从上面也可以知道此时的callback是不为null的,所以会执行executeCallbacks,最终会执行Activity的onCreate方法.此时根Activity就已经启动成功了。executeLifecycleState方法是用来改变活动的生命周期状态的,如果是根Activity的启动,最终将会执行onStart和onResume方法。下面来分析这两个方法

2.1 执行onCreate方法

来看看executeCallbacks这个方法。

frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java

    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null) {
            // No callbacks to execute, return early.
            return;
        }
        ......
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            //此时item为LaunchActivityItem
            final ClientTransactionItem item = callbacks.get(i);
            ......
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ......
        }
    }
复制代码

从上面的分析我们知道根Activity启动时这个callback的ClientTransactionItem为LaunchActivityItem,所以会执行LaunchActivityItem的execute方法。

frameworks\base\core\java\android\app\servertransaction\LaunchActivityItem.java

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
		//此client为ActivityThread
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
复制代码

上面的client为ActivityThread,所以会继续调用ActivityThread的handleLaunchActivity方法,如下。

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        mSomeActivitiesChanged = true;
        //启动Activity
        final Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            .....
        } else {
            //如果出现错误就通知AMS停止活动
            try {
				//停止Activity
                ActivityManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        return a;
    }
复制代码

在上述方法中将调用performLaunchActivity来启动活动,如下

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //ActivityInfo用于存储代码和AndroidManifes设置的Activity和receiver节点信息,
        //比如Activity的theme和launchMode
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
			//获取APK文件的描述类LoadedApk
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
		//获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名
        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的上下文环境
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();

		    //用类加载器来创建该Activity的实例
            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);
            }
        }
        ...

        try {
			//创建Application,makeApplication会调用Application的onCreate方法
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                ....
                //初始化Activity,创建Window对象(PhoneWindow)并实现Activity和Window相关联
                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);

                ....
                //设置主题    
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                //启动活动
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ....
            }

			//设置生命周期为onCreate
            r.setState(ON_CREATE);
        } 
        ...
        return activity;
    }
复制代码

该方法代码很多,要干的事情也挺多的,并且都很重要,通过注释应该可以知道这个方法的任务,当干完所有事后得将当前的生命周期设置为ON_CREATE。我们重点关注启动活动的代码mInstrumentation.callActivityOnCreate,可以知道在这里将会调用Instrumentation的callActivityOnCreate来启动活动。

frameworks\base\core\java\android\app\Instrumentation.java

    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
复制代码

而callActivityOnCreate将调用Activity的performCreate,如下

frameworks\base\core\java\android\app\Activity.java

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    @UnsupportedAppUsage
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ....
		//调用Activity的onCreate,根Activity启动成功
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }
复制代码

看得到这眼泪是否哗啦啦啦的流下了,终于看到熟悉的东西了,在Activity的performCreate中将执行onCreate,也就是我们在开发中所熟悉的onCreate,“终于等到你,还好我们没放弃”,讲到这,根Activity就已经启动了,我们的万里长征也应该结束了,但是身为万里长征的首席指挥官,总不能一结束就撒手不管吧。所以让我们继续来看看结束后的维护工作。

2.2 执行onStart方法

从上面分析中我们知道onCreate已经被调用,且生命周期的状态是ON_CREATE,故executeCallbacks已经执行完毕,所以开始执行executeLifecycleState方法。如下

frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        ....
        // 执行当前生命周期状态之前的状态
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

        //切换状态
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
复制代码

在executeLifecycleState方法中,会先执行cycleToPath,从上面的分析我们已经知道当根Activity启动时,此时的lifecycleItem为ResumeActivityItem,故调用lifecycleItem.getTargetState时将得到ON_RESUME状态,让我们来瞧瞧cycleToPath方法。

    private void cycleToPath(ActivityClientRecord r, int finish,
            boolean excludeLastState) {
        final int start = r.getLifecycleState();
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path);
    }
复制代码

由于onCreate方法已经执行,所以start为ON_CREATE,而finish为上面传递的ON_RESUME,excludeLastState是否移除最后的状态为true。让我们来看看getLifecyclePath这个方法

frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java

    public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
        ...
        if (finish >= start) {
            // 添加start到finish之间的周期状态
            for (int i = start + 1; i <= finish; i++) {
                mLifecycleSequence.add(i);
            }
        } 
        ...
        // 根据需求移除最后的状态
        if (excludeLastState && mLifecycleSequence.size() != 0) {
            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
        }

        return mLifecycleSequence;
    }

public abstract class ActivityLifecycleItem extends ClientTransactionItem {
    .....
    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;
    public static final int ON_RESTART = 7;
    ...
}

复制代码

在getLifecyclePath这个方法我们知道start为ON_CREATE,finish为ON_RESUME,那么如何知道start和finish的大小关系呢?在ActivityLifecycleItem中我们可以发现这些状态的定义,从定义中可以发现finish>=start,所以我们只关注这部分的逻辑处理,可以发现ON_CREATE和ON_RESUME中间还有ON_START这个状态,所以mLifecycleSequence将添加ON_START和ON_RESUME状态,但是又因为excludeLastState为true,所以最后会移除掉ON_RESUME状态,故返回的类型只包含ON_START状态。故cycleToPath方法中的path中将只包含ON_START状态,然后继续执行performLifecycleSequence方法。

    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            log("Transitioning to state: " + state);
            switch (state) {
                .....
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                 ......
            }
        }
    }
复制代码

因为path只包含ON_START状态,所以只执行ActivityThread的handleStartActivity方法。

frameworks/base/core/java/android/app/ActivityThread.java

	public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        ...
        // Start
        activity.performStart("handleStartActivity");
        r.setState(ON_START);
        ...
    }
复制代码

frameworks/base/core/java/android/app/Activity.java

final void performStart(String reason) {
    ...
     mInstrumentation.callActivityOnStart(this);
    ...
}
复制代码

frameworks/base/core/java/android/app/Instrumentation.java

    public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }
复制代码

从上面可以发现ActivityThread.handleStartActivity经过多次跳转最终会执行activity.onStart方法,至此cycleToPath方法执行完毕。

2.3 执行onResume方法

让我们回到executeLifecycleState这个方法,执行完cycleToPath方法后将执行lifecycleItem.execute,即ResumeActivityItem的execute方法。

frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        //此client为ActivityThread
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
复制代码

frameworks/base/core/java/android/app/ActivityThread.java

    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        ...
        // TODO Push resumeArgs into the activity for consideration
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        ...
        Looper.myQueue().addIdleHandler(new Idler());
        ...
    }

    public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
            String reason) {
        ...
        try {
            ...
            r.activity.performResume(r.startsNotResumed, reason);
            r.state = null;
            r.persistentState = null;
            //设置当前状态为ON_RESUME
            r.setState(ON_RESUME);
        } 
        ...
        return r;
    }
复制代码

frameworks/base/core/java/android/app/Activity.java

    final void performResume(boolean followedByPause, String reason) {
        performRestart(true /* start */, reason);
        ...
        // mResumed is set by the instrumentation
        mInstrumentation.callActivityOnResume(this);
        ...
    }
复制代码

frameworks/base/core/java/android/app/Instrumentation.java

    public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();
        ...
    }
复制代码

可以发现其实执行onCreate,onStart,onResume的流程大致上是类似的,通过多次调用最终将会调用Activity的onResume方法,至此Activity真正启动完毕!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Activity启动流程(二) 的相关文章

  • 人体姿态估计资源大列表(Human Pose Estimation)

    基础 xff1a Human Pose Estimation人体姿态估计综述调研人体姿态估计数据集整理 xff08 Pose Estimation Keypoint xff09 姿态估计的两个数据集COCO和MPII的认识 Human Po
  • DIY小四轴之电路设计(一)

    DIY小四轴之电路设计 xff08 一 xff09 写在前面 前一阵时间一直在做四轴飞行器 xff0c 略有一点收获吧 xff0c 在这里分享出来 xff0c 一方面算是对自己的总结 xff0c 另一方面希望能给想做小四轴的读者一些思路 本
  • DIY小四轴之电路设计(二)

    DIY小四轴之电路设计 xff08 二 xff09 上次我分析了四轴电源的电路 xff0c 这次我们来看电机驱动与传感器电路 三 空心杯电机驱动电路 一般的小型四轴都选用空心杯电机来驱动旋翼 xff0c 空心杯电机不仅节能而且灵敏 xff0
  • ubuntu 18.04 vnc server开机自启动

    转自 xff1a https blog csdn net lixiaotao 1 article details 90140979 1 首先确定vncserver 以正确安装到linux系统 xff1b 2 设置vncserver随系统自启
  • vnc viewer灰屏的解决方法

    vnc能够连接上 xff0c 但是进入界面灰屏 先关闭当前打开的vnc xff1a vncserver kill 88 然后修改权限 xff1a chmod 43 x vnc xstartup 然后重新打开vnc vncserver geo
  • samba 常用命令

    没怎么修改配置 xff0c 但有时需要修改时 xff0c 又是搜索一番 xff0c 故将常用的在此备份一下 修改samba配置 xff1a span class token function sudo span span class tok
  • .rst 语法+简明教程

    reStructuredText 是扩展名为 rst的纯文本文件 xff0c 含义为 34 重新构建的文本 34 xff0c 也被简称为 xff1a RST或reST xff1b 是Python编程语言的Docutils项目的一部分 xff
  • TG_7100b准备开发环境

    请在 64 位 Ubuntu 下搭建开发环境 Win10 系统可以在应用商店下载安装 Ubuntu18 04 LTS 其他用户可以安装虚拟机软件 以下为基于 Ubuntu 环境开发和编译 SDK 时需要用到的库和依赖包 xff0c 请您按顺
  • C++ STL中各容器内存、优劣的分析

    STL有三大核心部分 xff1a 容器 xff08 Container xff09 算法 xff08 Algorithms xff09 迭代器 xff08 Iterator xff09 以下介绍容器相关内容 xff1a 各种容器的元素在内存
  • 给自己时间沉淀下来

    像很多学长学姐当初一样 xff0c 我也到了繁忙的大四 这个尴尬的时间 xff0c 要选择 xff0c 要放弃 开始实习 xff0c 去窥探一下外面的世界 经过一个月的测试工作 xff0c 开始发现自己与别人的差距还是很大 再继续试水 xf
  • docker安装使用系列二之容器、镜像、仓库使用实例分析

    可能大家对docker了解不深 xff0c 这里再简单赘述一下docker这款利器 1 什么是docker Doker是基于GO语言实现的云开源项目 xff0c 通过对应用组件的封装 分发 部署 运行等生命周期的管理 xff0c 达到应用组
  • 图像处理之opencv库使用小结

    OpenCV是一个基于BSD许可 xff08 开源 xff09 发行的跨平台计算机视觉库 xff0c 可以运行在Linux Windows Android和Mac OS操作系统上 它轻量级而且高效 由一系列 C 函数和少量 C 43 43
  • react 启动项目遇到的问题

    当启动react 项目时遇到 xff1a 39 react scripts 39 不是内部或外部命令 xff0c 也不是可运行的程序 npm install npm install 下载依赖遇到安装失败 xff0c 则依赖包删除不干净 xf
  • Android LED电子表时钟字体digital font

    字体效果如下图所示 xff1a 这种类型的字体样式会被一些UI设计用于Android APP中时钟显示 xff0c 比如交通灯倒计时 实现这种字体样式 xff0c 先导入一个字体包 xff1a digital ttf 这个digital t
  • Android音视频处理之MediaCodec

    MediaCodec是Android中媒体编解码器 xff0c 可以对媒体进行编 解码 MediaCodec采用同步 异步方式处理数据 xff0c 并且使用了一组输入输出缓存 xff08 ByteBuffer xff09 通过请求一个空的输
  • 计算相机投影矩阵(含代码)(Python)

    计算相机投影矩阵 xff08 含代码 xff09 xff08 Python xff09 前几天处理点云时 xff0c 需要使用到像片与3D点云的对应关系 在这边找了一圈没有发现直接可用的代码 xff0c 于是去GitHub试了一下 xff0
  • H264 SPS中得到宽高的代码(java)

    数据需要去掉头 xff0c SPS测试数据 byte buffer 61 new byte 103 66 64 12 38 5 7 56 7 124 2 得到结果宽320高240 public class H264SpsParser pri
  • git 调换提交顺序

    前两个commit交换顺序 1 查看提交历史 git log oneline 2 把要调整顺序的commit显示在vim中 git rebase i a33d521 a33d521用来确定commit范围 xff0c 表示从此提交开始到当前
  • android hmacSha256 加密

    public class HMACSHA256 public static String hmacSha256 String KEY String VALUE return hmacSha KEY VALUE 34 HmacSHA256 3
  • Java生成固定长度的随机字符串(以大小写字母和数字)

    public class RandomStringUtil public static ArrayList lt String gt strList 61 new ArrayList lt String gt public static R

随机推荐

  • Android reckon 控制项目打包版本

    reckon 用法 github地址 xff1a https github com ajoberstar reckon 根项目 gradle配置 buildscript apply from 39 versions gradle 39 re
  • ArrayList源码解析

    构造函数 Constructs an empty list with an initial capacity of ten 使用10个初始容量构造一个空的集合 public ArrayList super 用一个空的数组进行初始化 this
  • 2023年有效的rtsp,rtmp,hls流媒体测试地址整理汇总

    rtsp rtsp wowzaec2demo streamlock net vod mp4 BigBuckBunny 115k mov 已停用 rtsp wowzaec2demo streamlock net vod mp4 BigBuck
  • http请求

    HTTP请求报文 一个HTTP请求报文由请求行 xff08 request line xff09 请求头部 xff08 header xff09 空行和请求数据4个部分组成 1 请求行 请求行分为三个部分 xff1a 请求方法 请求地址和协
  • http响应报文

    HTTP响应报文主要由状态行 响应头部 空行以及响应数据组成 1 状态行 由3部分组成 xff0c 分别为 xff1a 协议版本 xff0c 状态码 xff0c 状态码描述 其中协议版本与请求报文一致 xff0c 状态码描述是对状态码的简单
  • centos7+jdk8+安装Elasticsearch6.0

    一 xff1a 为Elasticsearch准备用户 1 添加用户 Elasticsearch6 0需要使用非root用户启动 root 64 66 adduser ela root 64 66 passwd ela 2 授权用户 查看文件
  • Retrofit2 源码解析

    0 基本使用 1 Retrofit 将我们的 HTTP API 转换成一个 接口形式 所以我们第一步定义一个 interface public interface GitHubService 64 GET 34 user user repo
  • Android Studio插件的源文件位置——mac端

    有些时候安装插件后 xff0c 整个android studio都卡住了 xff0c 无法通过Android Studio gt preferences gt plugins来卸载 xff0c 这时候就需要找到安装位置 xff0c 进行删除
  • H.264编码基础知识详解

    一 编码基础概念 1 为什么要进行视频编码 xff1f 视频是由一帧帧图像组成 xff0c 就如常见的gif图片 xff0c 如果打开一张gif图片 xff0c 可以发现里面是由很多张图片组成 一般视频为了不让观众感觉到卡顿 xff0c 一
  • Android事件分发

    基本知识 什么是触摸事件 触摸事件 xff0c 是Android用来描述你的手对屏幕做的事情的最小单元 关键词有两个 xff1a 手势 xff08 你的手对屏幕做的事情 xff09 最小单元 所谓手势 xff0c 就是比如按下 移动 抬起
  • HashMap这一篇就够了

    介绍下 HashMap 的底层数据结构 现在用的都是 JDK 1 8 xff0c 底层是由 数组 43 链表 43 红黑树 组成 xff0c 如下图 xff0c 而在 JDK 1 8 之前是由 数组 43 链表 组成 为什么要改成 数组 4
  • Activity的结构分析

    1 结构介绍 大伙儿应该都知道 xff0c Activity的结构分为三层 xff0c 分别是 xff1a Activity Window和View xff0c 不同层承担着不同的责任 上面的图简单的描述了Activity整个结构的构建流程
  • LinkedBlockingQueue

    一 类签名 从类名可知 xff0c LinkedBlockingQueue是基于链表实现的阻塞队列 public class LinkedBlockingQueue lt E gt extends AbstractQueue lt E gt
  • UDP Socket

    UDP的Java支持 UDP协议提供的服务不同于TCP协议的端到端服务 xff0c 它是面向非连接的 xff0c 属不可靠协议 xff0c UDP套接字在使用前不需要进行连接 实际上 xff0c UDP协议只实现了两个功能 xff1a 1
  • volatile

    把代码块声明为 synchronized xff0c 有两个重要后果 xff0c 通常是指该代码具有 原子性 xff08 atomicity xff09 和 可见性 xff08 visibility xff09 原子性意味着个时刻 xff0
  • Android 相机预览方向和拍照方向

    我们知道手机 Camera 的图像数据都是来自于摄像头硬件的图像传感器 xff08 Image Sensor xff09 xff0c 这个 Sensor 被固定到手机之后是有一个默认的取景方向的 xff0c 这个方向如下图所示 xff0c
  • Python无参装饰器

    一 什么是装饰器 定义一个函数 xff0c 该函数可为其他函数添加额外的功能 二 何时用装饰器 需要在不修改被装饰对象源代码及其调用方式时 xff0c 为被装饰对象添加额外的功能 三 如何写一个装饰器 现在我们有如下一个函数help xff
  • typedef的用法

    typedef中声明的类型在变量名的位置出现 什么意思呢 xff0c 我们回头来看 我们是怎么声明int类型变量的 xff1f int Typename 像上面这样 xff0c 对不对 xff1f 那么用typedef之后呢 xff1f 把
  • Activity启动流程(一)

    Launcher进程请求AMSAMS发送创建应用进程请求Zygote进程接受请求并孵化应用进程应用进程启动ActivityThread 一 Launcher进程请求AMS 上面我们提到根Activity的启动流程其实就是桌面上点击一个应用图
  • Activity启动流程(二)

    应用进程绑定到AMSAMS发送启动Activity的请求ActivityThread的Handler处理启动Activity的请求 一 应用进程绑定到AMS 1 时序图 2 详细过程 在前面一篇我们知道当Zygote进程孵化出应用进程后会执