美文网首页
Activity启动流程

Activity启动流程

作者: 糖葫芦_倩倩 | 来源:发表于2020-10-15 14:34 被阅读0次

    最近在研究启动优化方面的知识,那么对于 Activity 的启动过程这方面的知识自然是逃不掉的,那么废话不多说,我们开始梳理。

    (文中基于sdk28, 不少有代码片段的地方,可能比较枯燥,我们只要把握主要流程即可~)

    1. 启动

    启动包括冷启动和热启动,本篇我们主要围绕冷启动做简述。(还不清楚冷启动和热启动的区别,就自行Google哦)

    2. 点击一个应用图标

    当我们在手机桌面开始点击一个应用图标的时候,此时应用就启动起来了,那么背后究竟发生了什么事,我们一起来看一下:

    2.1 startActivity

    Activity#startActivity

    @Override
        public void startActivity(Intent intent, @Nullable Bundle options) {
            if (options != null) {//不传 options为null
                startActivityForResult(intent, -1, options);
            } else {
                startActivityForResult(intent, -1);
            }
        }
    

    Activity#startActivityForResult

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
            if (mParent == null) {
                options = transferSpringboardActivityOptions(options);
                Instrumentation.ActivityResult ar = -----------//注释1
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);        
              ....
            }
        }
    

    注释1处: mInstrumentationInstrumentation 类型,调用了 execStartActivity 方法,其中 mMainThread.getApplicationThread() 需要我们重点关注。

    mMainThread -----> ActivityThread 类型
    getApplicationThread() 返回 ApplicationThread 类型, 而 ApplicationThread 则是 ActivityThread 的一个内部类,大致如下:

    class ActivityThread{
    ...
      public ApplicationThread getApplicationThread()
        {
            return mAppThread;
        }
      private class ApplicationThread extends IApplicationThread.Stub {
                .....
      }
    ...
    }
    

    OK ,直到了 ApplicationThread 我们继续,调用了 Instrumentation.execStartActivity 我们需要点进去看一下:

    2.2 Instrumentation#execStartActivity

    public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
            IApplicationThread whoThread = (IApplicationThread) contextThread; //----->注释1
            ...
       
                intent.migrateExtraStreamToClipData();
                intent.prepareToLeaveProcess(who);
                int result = ActivityManager.getService() //------->注释2
                    .startActivity(whoThread, who.getBasePackageName(), intent,
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            token, target != null ? target.mEmbeddedID : null,
                            requestCode, 0, null, options);
                checkStartActivityResult(result, intent);
           ...
            return null;
        }
    

    注释1: 其中我们上面说的 ApplicationThread 被转化成 IApplicationThread 是一个 IBinder 类型 , 因为ApplicationThread继承了 IApplicationThread.Stub 是不是很眼熟,类似于我们那个aidl 自动生成的那个代码,你可以认为是代理类。

    接着往下,注释2: ActivityManager.getService 返回 IActivityManager 类型 ,看下面代码:

     public static IActivityManager getService() {
            return IActivityManagerSingleton.get();
        }
    
        private static final Singleton<IActivityManager> IActivityManagerSingleton =
                new Singleton<IActivityManager>() {
                    @Override
                    protected IActivityManager create() {
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                        final IActivityManager am = IActivityManager.Stub.asInterface(b);
                        return am;
                    }
                };
    

    ServiceManager 获取到服务,其实就是我们的 ActivityManagerService 对象,它继承了IActivityManager.Stub 为具体实现类

    public class ActivityManagerService extends IActivityManager.Stub..{
      ....
    }
    

    最终调用实际是 ActivityManagerService 的 startActiviy方法,通过获取远程服务获取到代理类,调用了远程服务,此时由客户端进程转换到远程服务端进程

    2.3 ActivityManagerService#startActivity

    ActivityManagerService 这里简称 AMS,这里代码就比较多了,我们只看一些对流程上比较重要的方法:

    @Override
        public final int startActivity(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                    resultWho, requestCode, startFlags, profilerInfo, bOptions,
                    UserHandle.getCallingUserId());
        }
    

    里面可以看到又调用了 startActivityAsUser() 方法,继续走:

    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
                boolean validateIncomingUser) {
               ...
            // TODO: Switch to user app stacks here.
            return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                    .setCaller(caller)
                    .setCallingPackage(callingPackage)
                    .setResolvedType(resolvedType)
                    .setResultTo(resultTo)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setStartFlags(startFlags)
                    .setProfilerInfo(profilerInfo)
                    .setActivityOptions(bOptions)
                    .setMayWait(userId)
                    .execute();
        }
    

    只看到最后调用了一个 execute() 方法,那么看是谁的 execute() 方法, obtainStarter() 方法返回 ActivityStarter 类型的对象,那么就是它的,走进去看看:
    ActivityStarter#execute

    int execute() {
            try {
                if (mRequest.mayWait) {
                    return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                            mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                            mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                            mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                            mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                            mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                            mRequest.inTask, mRequest.reason,
                            mRequest.allowPendingRemoteAnimationRegistryLookup);
                } else {
                    return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                            mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                            mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                            mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                            mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                            mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                            mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                            mRequest.outActivity, mRequest.inTask, mRequest.reason,
                            mRequest.allowPendingRemoteAnimationRegistryLookup);
                }
            } finally {
                onExecutionComplete();
            }
        }
    

    这个 mRequest.mayWaittrue ,因为前面我们在启动的时候设置了:

    image.png
    image.png
    所以我们就可以直接看 startActivityMayWait 这个方法了。

    这个方法就比较长了,我看了好长时间,看到最后方法返回 res,自然而然就比较关注这个 res 赋值是什么,赋值我拿了出来:

     private int startActivityMayWait(IApplicationThread caller, int callingUid,
                String callingPackage, Intent intent, String resolvedType,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode, int startFlags,
                ProfilerInfo profilerInfo, WaitResult outResult,
                Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
                int userId, TaskRecord inTask, String reason,
                boolean allowPendingRemoteAnimationRegistryLookup) {
          ....
                  final ActivityRecord[] outRecord = new ActivityRecord[1];
                  int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                        voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                        callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                        ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                        allowPendingRemoteAnimationRegistryLookup);
                  return res;
          ....
    }
    

    这个 startActivity 继续调用调用:

    image.png
    方法里最终 return 又还是继续调用 startActivity 方法 :
    image.png
    代码如下:
    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                    int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                    ActivityRecord[] outActivity) {
            int result = START_CANCELED;
            try {
                mService.mWindowManager.deferSurfaceLayout();
                result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, doResume, options, inTask, outActivity);
            } finally {
                // If we are not able to proceed, disassociate the activity from the task. Leaving an
                // activity in an incomplete state can lead to issues, such as performing operations
                // without a window container.
                final ActivityStack stack = mStartActivity.getStack();
                if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
                    stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                            null /* intentResultData */, "startActivity", true /* oomAdj */);
                }
                mService.mWindowManager.continueSurfaceLayout();
            }
    
            postStartActivityProcessing(r, result, mTargetStack);
    
            return result;
        }
    

    因为最后返回 result 所以我们还是看 result 的赋值, 调用了 startActivityUnchecked 方法 最后返回 START_SUCCESS 应该就是最后的方法了吧,目测感觉应该要到头了,看了一下这个方法有点长:

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
            ....
            //把目标栈移动到前台
           reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
    
    if (dontStart) {
              
                topStack.mLastPausedActivity = null;
                if (mDoResume) {
                    mSupervisor.resumeFocusedStackTopActivityLocked();//--------注释1
                }           
              ...
              result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);//-------注释2
            }
            ....
    
    
    
            return START_SUCCESS;
    }
    

    注释1:ActivityStackSupervisor 负责将目标 Activity 放于栈顶 ;
    注释2:复用或者创建新的任务栈 ;

    2.4 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked

    boolean resumeFocusedStackTopActivityLocked() {
            return resumeFocusedStackTopActivityLocked(null, null, null);
        }
    
        boolean resumeFocusedStackTopActivityLocked(
                ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    
            if (!readyToResume()) {
                return false;
            }
    
            if (targetStack != null && isFocusedStack(targetStack)) {
                return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
    
            final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
            if (r == null || !r.isState(RESUMED)) {
                mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
            } else if (r.isState(RESUMED)) {
                // Kick off any lingering app transitions form the MoveTaskToFront operation.
                mFocusedStack.executeAppTransition(targetOptions);
            }
    
            return false;
        }
    

    result = resumeTopActivityInnerLocked(prev, options)
    这个方法就比较长,参考其它资料,里面比较重要的就是:

    .....
    if (next.app != null && next.app.thread != null) {
      //把要启动Activity进程信息封装在一个 ClientTransaction 对象中了
    final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
                                next.appToken);
    //如果要启动的activity已经存在,就该resume了
    mStackSupervisor.scheduleResumeTopActivities();
    }else{
          //如果进程不存在,就要启动新的Activity
         mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    ....
    

    假如是第一次启动 Activity 就执行 mStackSupervisor.startSpecificActivityLocked() 方法,继续跟进去:

    void startSpecificActivityLocked(ActivityRecord r,
                boolean andResume, boolean checkConfig) {
            // Is this activity's application already running?
            ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                    r.info.applicationInfo.uid, true);
    
            getLaunchTimeTracker().setLaunchTime(r);
    
            if (app != null && app.thread != null) {
                try {
                    if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                            || !"android".equals(r.info.packageName)) {
                        // Don't add this if it is a platform component that is marked
                        // to run in multiple processes, because this is actually
                        // part of the framework so doesn't make sense to track as a
                        // separate apk in the process.
                        app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                                mService.mProcessStats);
                    }
                    realStartActivityLocked(r, app, andResume, checkConfig);
                    return;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting activity "
                            + r.intent.getComponent().flattenToShortString(), e);
                }
    
                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
    
            mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                    "activity", r.intent.getComponent(), false, false, true);
        }
    

    继续执行那就是 realStartActivityLocked() 方法:

     final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
    
      ....
          // Create activity launch transaction. 创建启动Activity的事务
                    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                            r.appToken);
                    //回调callback 是 LaunchActivityItem
                    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                            System.identityHashCode(r), r.info,
                            mergedConfiguration.getGlobalConfiguration(),
                            mergedConfiguration.getOverrideConfiguration(), r.compat,
                            r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                            r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                            profilerInfo));
                     final ActivityLifecycleItem lifecycleItem;
                    if (andResume) {
                        lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                    } else {
                        lifecycleItem = PauseActivityItem.obtain();
                    }
                    clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
                    // Schedule transaction. 最后开始执行了
                    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
      ....
    }
    

    这里可以看到生命周期的回调被封装成一个一个的 Item ,例如 : LaunchActivityItem , ResumeActivityItem , PauseActivityItem 光看名字也能大概猜出一点来。

    这里 mService 就是 AMS , getLifecycleManager() 获取到 ClientLifecycleManager 对象 , 调用 scheduleTransaction 方法 ;

    2.5 ClientLifecycleManager#scheduleTransaction

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            final IApplicationThread client = transaction.getClient();
            transaction.schedule();
            if (!(client instanceof Binder)) {
                // If client is not an instance of Binder - it's a remote call and at this point it is
                // safe to recycle the object. All objects used for local calls will be recycled after
                // the transaction is executed on client in ActivityThread.
                transaction.recycle();
            }
        }
    

    2.6 ClientTransaction#schedule

     public void schedule() throws RemoteException {
            mClient.scheduleTransaction(this);
        }
    

    mClientIApplicationThread 就是 ApplicationThread , 而 ApplicationThreadActivityThread 的一个内部类,执行了 scheduleTransaction 方法。

    此时你会发现,由原来的 Client 进程 ---------> AMS进程 ,现在又回到了 客户端进程了。

    Client 进程 ---------> AMS进程 ---------> Client 进程

    2.7 ActivityThread#ApplicationThread # scheduleTransaction

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

    因为 ActivityThread 继承了 ClientTransactionHandler ,在父类中实现了这个方法:

    2.8 ClientTransactionHandler#scheduleTransaction

    void scheduleTransaction(ClientTransaction transaction) {
            transaction.preExecute(this);
            sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    

    终于看到点能看懂的代码了,开始切换主线程了,因为看到了 sendMessage , 哈哈。
    发送了一个 ActivityThread.H.EXECUTE_TRANSACTION 消息 ,objtransaction , 继续到 ActivityThread 中看下:

    2.9 ActivityThread#mH

    public final class ActivityThread extends ClientTransactionHandler{
    
      //内部类H
     class H extends Handler {
          //很多消息类型,找到我们刚才发的消息类型 为159
         public static final int BIND_APPLICATION        = 110;
            public static final int EXIT_APPLICATION        = 111;
            public static final int RECEIVER                = 113;
    
          public static final int EXECUTE_TRANSACTION = 159;
            ........
        //处理消息
        case EXECUTE_TRANSACTION:
                        final ClientTransaction transaction = (ClientTransaction) msg.obj;
                        mTransactionExecutor.execute(transaction);
                       
                        break;
    }
    }
    

    找到对应的消息类型,开始处理消息,取出之前的 ClientTransaction , 并调用 其 execute 方法,继续跟进:

    然后你会发现 在 ClientTransaction 类中并没有 execute 方法,因为前面我们说过把生命周期都封装成一个一个的 Item 了, 启动 ActivityLauncheActivityItem
    所以我们应该去看 LaunchActivityItem

    3.0 LaunchActivityItem#execute

    该类继承了 ClientTransactionItem

    public class LaunchActivityItem extends ClientTransactionItem {
    
        @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.handleLaunchActivity(r, pendingActions, null /* customIntent */);
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }
    

    啊哈 ,好熟悉的代码,调用 handleLaunchActivity 方法,就是 ActivityThread 中的,继续走:

    3.1 ActivityThread#handleLaunchActivity

    @Override
        public Activity handleLaunchActivity(ActivityClientRecord r,
                PendingTransactionActions pendingActions, Intent customIntent) {
         
             ...
            final Activity a = performLaunchActivity(r, customIntent);
           ....
            return a;
        }
    

    3.2 ActivityThread#performLaunchActivity

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
          //创建ContextImpl
         ContextImpl appContext = createBaseContextForActivity(r);
            Activity activity = null;
    
            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);
                }
              //创建Application对象
               Application app = r.packageInfo.makeApplication(false, mInstrumentation);
              //创建Window对象
              Window window = null;
                    if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                        window = r.mPendingRemoveWindow;
                        r.mPendingRemoveWindow = null;
                        r.mPendingRemoveWindowManager = null;
                    }
                    appContext.setOuterContext(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);
    
              //调用Activity 的 onCreate() 方法
               mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    
    public void callActivityOnCreate(Activity activity, Bundle icicle,
                PersistableBundle persistentState) {
            prePerformCreate(activity);
            activity.performCreate(icicle, persistentState);
            postPerformCreate(activity);
        }
    

    3.3 Activity#performCreate

    final void performCreate(Bundle icicle) {
            performCreate(icicle, null);
        }
    
        final void performCreate(Bundle icicle, PersistableBundle persistentState) {
            mCanEnterPictureInPicture = true;
            restoreHasCurrentPermissionRequest(icicle);
            if (persistentState != null) {
                onCreate(icicle, persistentState); // 调用其 onCreate 方法
            } else {
                onCreate(icicle);
            }        
        }
    

    终于走到头了,看到了 onCreate() 方法,由于文章篇幅过长,总结放到下一篇,路过的朋友如果对你有帮助,能否为辛苦的糖葫芦点个赞👍再走啊~

    相关文章

      网友评论

          本文标题:Activity启动流程

          本文链接:https://www.haomeiwen.com/subject/nlsvyktx.html