美文网首页
ActivityManagerService--startAct

ActivityManagerService--startAct

作者: None_Ling | 来源:发表于2019-07-24 11:20 被阅读0次

流程图

该流程图为:当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
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
      ...  
      // 根据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
  • 处理startActivityForResult相关的接收者
  • 判断Intent中的Flag,Components,ActivityInfo是否为空,为空则返回错误
  • 检查启动Activity的权限,没有权限则返回
       ... 
       // 根据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) {
                    //  如果requestCode>=0,那么就先将启动者赋值为接收者
                    //  也就是resultRecord代表接收结果的ActivityRecord对象
                    //  如果requestCode小于0的话,那么resultRecord就一直为空,代表不需要接收结果
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
      ... 
       if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
            //  如果有该Flag,那么就需要重新调整结果的接收者了
            //  该Flag的作用,就是将结果返回给上一个Activity
            
            //  例如A--->B---C,A通过startActivityForResult启动B,而B通过startActivity并且
            //  携带该参数的话,那么C的结果会返回给A,而不通过B
            if (requestCode >= 0) {
                ActivityOptions.abort(options);
                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
            }
            // 将原来的接收者赋值给resultRecord
            resultRecord = sourceRecord.resultTo;
            if (resultRecord != null && !resultRecord.isInStackLocked()) {
                resultRecord = null;
            }
            //  同样赋值resultWho,这是个String类型的,同样代表Activity
            resultWho = sourceRecord.resultWho;
            //  将requestCode也重新赋值
            requestCode = sourceRecord.requestCode;
            //  将启动者的resultTo置空,代表不用接收结果
            sourceRecord.resultTo = null;
            //  也就是A接收B的结果,而B通过FLAG_ACTIVITY_FORWARTD_RESULT,将原本B接收结果改成A接收结果
            if (resultRecord != null) {
                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
            }
            if (sourceRecord.launchedFromUid == callingUid) {
                callingPackage = sourceRecord.launchedFromPackage;
            }
        }
      // 检查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继续启动
    // 根据函数参数初始化要启动的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
      ...
      //  找到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{
            //  如果即将启动的Activity中有需要返回的结果的话
            ArrayList<ResultInfo> a = next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
                         //  则通过该函数将结果分发给对应的进程Activity的onActivityResult
                        next.app.thread.scheduleSendResult(next.appToken, a);
                    }
                }
                //   同理,处理newIntent
                if (next.newIntents != null) {
                    next.app.thread.scheduleNewIntent(
                            next.newIntents, next.appToken, false /* andPause */);
                }
            ...
            //  设置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启动进程
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
// 只有所有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的消息
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
....
sendMessage(H.LAUNCH_ACTIVITY, r);

ApplicationThread.handleLaunchActivity(用户进程)

H类接收到该消息后,会调用handleLaunchActivity,至此,Activity的启动结束。

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

ActivityThread.Idler

当目标Activity进程主线程队列为空时,会发送activityIdle的消息给ActivityManagerService,来处理接下来的onStop流程。

private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            ...
            if (a != null) {
                mNewActivities = null;
                IActivityManager am = ActivityManager.getService();
                ActivityClientRecord prev;
                do {
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            throw ex.rethrowFromSystemServer();
                        }
                    }
                 ...
                } while (a != null);
            }
           ...
            return false;
        }
    }

ActivityStackSupervisor.activityIdleInternalLocked

主要是调用ActivityStackSupervisor.activityIdleInternalLocked函数,在该函数中,会处理待onStop或者finish的函数

 // Atomically retrieve all of the other things to do.
        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
                true /* remove */, processPausingActivities);
        NS = stops != null ? stops.size() : 0;
        if ((NF = mFinishingActivities.size()) > 0) {
            finishes = new ArrayList<>(mFinishingActivities);
            mFinishingActivities.clear();
        }

        if (mStartingUsers.size() > 0) {
            startingUsers = new ArrayList<>(mStartingUsers);
            mStartingUsers.clear();
        }

        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NS; i++) {
            r = stops.get(i);
            final ActivityStack stack = r.getStack();
            if (stack != null) {
                //  如果是finishing的话
                if (r.finishing) {
                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
                } else {
                    //  如果是stop的话
                    stack.stopActivityLocked(r);
                }
            }
        }

相关文章

  • ActivityManagerService--startAct

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

网友评论

      本文标题:ActivityManagerService--startAct

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