前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ActivityManagerService--startActivity的流程

ActivityManagerService--startActivity的流程

作者头像
None_Ling
发布2019-07-25 14:10:30
1.4K0
发布2019-07-25 14:10:30
举报
文章被收录于专栏:Android相关Android相关

流程图

该流程图为:当Activity目标进程不存在时,启动Activity的流程。若进程相同的话,也只是省略了启动进程的步骤。

startActivity的流程图

在Activity启动的时候,所处的Task以及Stack都与进程无关。即,Task与Stack与进程不是绑定在一起的

启动流程

Activity.startActivity(用户进程)

startActivity会调用startActivitiyForResult,只是requestCode传入的是-1,而正常的requestCode为正数。

  • ApplicationThread
    • ActivityThread.ApplicationThread对象
    • ActivityThread对象初始化的时候,初始化唯一的ApplicationThread对象
    • 主要用于AMS告知用户进程Activity、Service生命周期的事件
  • mToken
    • IBinder对象
    • 在Activity创建的时候,AMS创建的Token
    • 主要用来在AMS中通过该Token,找到对应的ActivityRecord
代码语言:javascript
复制
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
            ...
            Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
            ...
ActivityStarter.startActivityMayWait(System_Server进程)

通过Instrumentation.execStartActivity经过IPC调用,调用到AMS的startActivity,进入后该函数后,会调用到ActivityStarter.startActivityMayWait

  • 通过PackageManagerService解析intent找到对应的ActivityInfo对象
  • 找到当前正在显示的ActivityStack
  • 初始化调用者的Pid以及Uid
代码语言:javascript
复制
      ...  
      // 根据intent以及userId查找匹配的Activity类,通过PackageManagerService根据
      // ComponentName,Action,Category来找到最合适的Activity类信息
      ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
      ...
      ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
      ···
      //  获取当前正在显示的ActivityStack
      final ActivityStack stack;
      if (container == null || container.mStack.isOnHomeDisplay()) {
          stack = mSupervisor.mFocusedStack;
      } else {
          stack = container.mStack;
      }
      //  调用startActivityLocked
      int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask, reason)
      ...
ActivityStater.startActivity(System_Server进程)

startActivityLocked会直接调用startActivity

  • 找到调用者进程
  • 根据token找到调用者的ActivityRecord,以及requestRecord
  • 判断Intent中的Flag,Components,ActivityInfo是否为空,为空则返回错误
  • 检查启动Activity的权限,没有权限则返回
代码语言:javascript
复制
       ... 
       // 根据ApplicationThread找到调用者的进程信息
       ProcessRecord callerApp = null;
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
        }
       ...
        // 调用者的ActivityRecord
       ActivityRecord sourceRecord = null;
        // 接收结果的ActivityRecord
       ActivityRecord resultRecord = null;
        if (resultTo != null) {
            // 根据调用者的mToken(即resultTo)查找所有Activity栈中的ActivityRecord
            sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                    "Will send result to " + resultTo + " " + sourceRecord);
            if (sourceRecord != null) {
                // 如果通过startActivityForResult启动的,则将接收结果的ActivityRecord赋值,用于接收Activity的结果
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
      ... 
      // 处理FLAG_ACTIVITY_FORWARD_RESULT,后续在startActivityForResult篇继续说明
      if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
            ...
        }
      // 检查Intent中的Components是否为空,为空直接返回
       if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
           err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }
      // 判断是否有找到匹配的Activity,没有则返回
        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }
       // 处理语音相关数据,暂时忽略不看
        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
                && sourceRecord.getTask().voiceSession != null) {
           ...
        }
        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
            ...
        }
        // 通过AMS开始检查uid启动Activity的权限
        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
                resultRecord, resultStack, options);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
        ... 
        //  创建一个新的ActivityRecord
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, container, options, sourceRecord);
      // 调用startActivity
      return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
ActivityStarter.startActivityUnchecked(System_Server进程)

接着会调用startActivityUnchecked函数:

  • 将要启动的ActivityRecord、Intent、Task赋值保存到成员变量中
  • 根据LaunchMode以及Flag找到符合条件的Task
  • 根据LaunchMode以及Flag,清理目标Task上面的Activity,以及回调onNewIntent
  • 如果没有能复用的Task的话,则需要创建一个新的Task
  • 继续调用ActivityStack.startActivityLocked继续启动
代码语言:javascript
复制
    // 根据函数参数初始化要启动的Activity的mIntent等成员变量
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor);
    // 计算要启动的Task的Flag,主要是添加FLAG_NEW_TASK
    computeLaunchingTaskFlags();
    // 计算调用者的Stack
    computeSourceStack();
    // reusedActivity主要用来找TaskId ,根据launchMode以及Intent.Flag来找到可以重复使用的Task
    ActivityRecord reusedActivity = getReusableIntentActivity();
    ...
    // 如果可以复用Task的话
    if (reusedActivity != null) {
           ...
           // mStartActivity代表要启动的Activity,然后为该Activity的Task赋值
           if (mStartActivity.getTask() == null) {
                mStartActivity.setTask(reusedActivity.getTask());
            }
           // 设置Task的Intent
            if (reusedActivity.getTask().intent == null) {
                reusedActivity.getTask().setIntent(mStartActivity);
            }
            // 处理CLEAR_TOP以及singleTask、SingleInstance的情况
            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
                    || mLaunchSingleInstance || mLaunchSingleTask) {
                final TaskRecord task = reusedActivity.getTask();
                // 清理复用的Activity上方的其他Activity
                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                        mLaunchFlags);
                if (reusedActivity.getTask() == null) {
                    reusedActivity.setTask(task);
                }

                if (top != null) {
                    if (top.frontOfTask) {
                        top.getTask().setIntent(mStartActivity);
                    }
                    // 回调复用的Activity的onNewIntent
                    top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
                            mStartActivity.launchedFromPackage);
                }
            }
          // 将目标Activity的Task移动到前台
          reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
          ...
          // 如果是FLAG_NEW_TASK设置,并且没有可重用的Task的话,就会生成一个新的Task,并且切换到前台
          if (!mAddingToTask && mReuseTask == null) {
                // We didn't do anything...  but it was needed (a.k.a., client don't use that
                // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
                resumeTargetStackIfNeeded();
                if (outActivity != null && outActivity.length > 0) {
                    outActivity[0] = reusedActivity;
                }
                return START_TASK_TO_FRONT;
            }
          ...
          boolean newTask = false;
          final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTask() : null;
          // Should this be considered a new task?
          int result = START_SUCCESS;
          if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            // 如果不需要返回结果,并且没有匹配的Task,并且FLAG_ACTIVITY_NEW_TASK匹配了,那么就需要重新创建一个新的task
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
          } else if (mSourceRecord != null) {
            // 否则就使用调用者的Task
            result = setTaskFromSourceRecord();
          } else if (mInTask != null) {
            // 如果调用者也为空,则使用复用的Task
            result = setTaskFromInTask();
          } else {
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            // 如果不是被已经存在的Activity启动的,可能从Service启动的,并且不是属于一个新的Task的话,就需要重新创建一个Task
            setTaskToCurrentTopOrCreateNewTask();
          }
          ...
          // 继续调用startActivityLocked,主要处理窗口的一些事情
          mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
          ...
          //  return startActivity(r, sourceRecord, voiceSession, voiceInteractor,startFlags, true,options, inTask, outActivity); doResume是true
          if (mDoResume) {
            final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                mWindowManager.executeAppTransition();
            } else {
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                // 继续执行resume操作
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
ActivityStack.resumeTopActivityInnerLocked(System_Server进程)

resumeFocusedStackTopActivityLocked操作最后会调用ActivityStack.resumeTopActivityInnerLocked函数:

  • 判断系统状态是否在休眠,如果是则先返回
  • 从Stopping等列表中移除即将启动的Activity
  • 等待所有需要Pause的Activity执行Pause结束后,再继续
  • Pause当前显示的Activity
  • 等待所有的Activity都Pause完毕后,判断目标进程是否启动
  • 如果进程启动,则调用scheduleResumeActivity开始启动Activity
  • 进程未启动,则调用startSpecificActivityLocked启动进程并且启动Activity
代码语言:javascript
复制
      ...
      //  找到FocusedTask的顶部的ActivityRecord,也就是即将启动的Activity
       final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
      // 如果系统正在休眠或者关机,并且顶部Activity暂停,没有需要resume的Activity的话,直接返回即可
      if (mService.isSleepingOrShuttingDownLocked()
                && mLastPausedActivity == next
                && mStackSupervisor.allPausedActivitiesComplete()) {
        ...
        return false;
      }
      //  从Stopping以及Sleeping的队列中移除即将启动的Activity
      mStackSupervisor.mStoppingActivities.remove(next);
      mStackSupervisor.mGoingToSleepActivities.remove(next);
      next.sleeping = false;
      mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
      //  如果当前有正在Pausing的Activity的话,则先等所有Activity都Pausing完毕后再执行Resume流程
      if (!mStackSupervisor.allPausedActivitiesComplete()) {
            return false;
        }
      ...
      //  开始Pause上一个Activity,通过ApplicationThread发送要暂停的消息,而在用户进程
      //  会根据mToken找到要暂停的Activity,然后通过H发送Pausing的消息
      boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
      if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
      }
      if (pausing && !resumeWhilePausing) {
            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
                    "resumeTopActivityLocked: Skip resume: need to start pausing");
           //  如果正在PausingActivity,并且不支持Resume_While_Pausing的标识位的话,则需要等待Activity Pause完毕才能启动
            if (next.app != null && next.app.thread != null) {
                mService.updateLruProcessLocked(next.app, true, null);
            }
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return true;
        } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                mStackSupervisor.allResumedActivitiesComplete()) {
             // 如果不用等待Pause结束的话,则判断要启动的Activity与当前处于Resume的Activity是否是同一个,如果是的话,则直接返回
            executeAppTransition(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }     
        // 处理Windowmanager的动画
        ...
        //  判断目标进程是否已经启动
        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {
             //  目标进程已经启动
            try{
            ...
            //  设置mResumedActivity为即将启动的Activity
            setResumedActivityLocked(next, "resumeTopActivityInnerLocked");
            mService.updateLruProcessLocked(next.app, true, null);
            updateLRUListLocked(next);
            //  更新所有进程的OomAdj
            mService.updateOomAdjLocked();        
            ...  
            //  调用该函数向目标进程发送ResumeActivity的请求
            next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                        mService.isNextTransitionForward(), resumeAnimOptions);

            }catch(Exception e){
                 // 如果发生任何异常,调用该函数重启Activity
                 mStackSupervisor.startSpecificActivityLocked(next, true, false);
            }
        } else {
            //  目标进程未启动
            ...
            //  调用该函数启动Activity
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

ActivityStackSupervisor. startSpecificActivityLocked(System_Server进程)

  • 如果目标进程已经启动,则调用realStartActivityLocked启动Activity
  • 如果目标进程未启动,则调用startProcessLocked启动进程
代码语言:javascript
复制
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
//  判断进程是否已经启动,如果已经启动,则调用realStartActivityLocked
if (app != null && app.thread != null) {
      ...
      realStartActivityLocked(r, app, andResume, checkConfig);
      ...
}
// 如果进程没有启动,则调用startProcessLocked,向Zygote进程通过Socket发送fork命令,创建进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);

ActivityStackSupervisor.realStartActivityLocked(System_Server进程)

  • 判断所有的Activity都处于Pause状态
  • 回调用户进程,调用scheduleLaunchActivity
代码语言:javascript
复制
// 只有所有Activity Pause完毕才能开始启动
 if (!allPausedActivitiesComplete()) {
            return false;
 }
...
//  通过IApplicationThread回调到用户进程,调用scheduleLaunchActivity
 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
...

ApplicationThread.scheduleLaunchActivity(用户进程)

  • 创建客户端的ActivityClientRecord对象,保存mToken
  • 发送H.LAUNCH_ACTIVITY的消息
代码语言:javascript
复制
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
....
sendMessage(H.LAUNCH_ACTIVITY, r);

ApplicationThread.handleLaunchActivity(用户进程)

H类接收到该消息后,会调用handleLaunchActivity

  • 初始化WindowManager
  • 调用performLaunchActivity,创建Activity对象,并且回调onCreate、onStart等函数
  • 调用handleResumeActivity,回调onResume函数
代码语言:javascript
复制
...
Activity a = performLaunchActivity(r, customIntent);
...
if(a!=null){
    ...
    // 
    handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
    ...
}

至此,Activity的启动结束,而上一个Activity的onStop回调则是在新的Activity窗口变得可见时,才会将上一个Activity进入Stop。

ActivityRecord.onWindowsVisible

主要是调用ActivityStackSupervisor.scheduleIdleLocked函数,在该函数中,会回调Activity的onStop

代码语言:javascript
复制
 @Override
    public void onWindowsVisible() {
        synchronized (service) {
            mStackSupervisor.reportActivityVisibleLocked(this);
            if (!nowVisible) {
               ...
                if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
                    final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
                    if (size > 0) {
                       ...
                        mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
                        mStackSupervisor.scheduleIdleLocked();
                    }
                } else {
                        mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
                            false /* remove */, true /* processPausingActivities */);
                }
                service.scheduleAppGcsLocked();
            }
        }
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.07.24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 流程图
  • 启动流程
    • Activity.startActivity(用户进程)
      • ActivityStarter.startActivityMayWait(System_Server进程)
        • ActivityStater.startActivity(System_Server进程)
          • ActivityStarter.startActivityUnchecked(System_Server进程)
            • ActivityStack.resumeTopActivityInnerLocked(System_Server进程)
            • ActivityStackSupervisor. startSpecificActivityLocked(System_Server进程)
            • ActivityStackSupervisor.realStartActivityLocked(System_Server进程)
            • ApplicationThread.scheduleLaunchActivity(用户进程)
            • ApplicationThread.handleLaunchActivity(用户进程)
            • ActivityRecord.onWindowsVisible
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档