Android app启动流程:startActivityMayWait分析(10)

  • A+
所属分类:AMS

activity的启动从ActivityManagerService最终会转到 frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java 里面的startActivityMayWait中来。

final int startActivityMayWait(IApplicationThread caller, int callingUid,   ...) {
      if (intent != null && intent.hasFileDescriptors()) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
      }

      boolean componentSpecified = intent.getComponent() != null;
      final Intent ephemeralIntent = new Intent(intent);
      intent = new Intent(intent);
  
      ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
      if (rInfo == null) {
        UserInfo userInfo = mSupervisor.getUserInfo(userId);
        if (userInfo != null && userInfo.isManagedProfile()) {
          UserManager userManager = UserManager.get(mService.mContext);
          boolean profileLockedAndParentUnlockingOrUnlocked = false;
          long token = Binder.clearCallingIdentity();
          try {
            UserInfo parent = userManager.getProfileParent(userId);
            profileLockedAndParentUnlockingOrUnlocked = (parent != null)
                && userManager.isUserUnlockingOrUnlocked(parent.id)
                && !userManager.isUserUnlockingOrUnlocked(userId);
          } finally {
            Binder.restoreCallingIdentity(token);
          }
          if (profileLockedAndParentUnlockingOrUnlocked) {
            rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                PackageManager.MATCH_DIRECT_BOOT_AWARE
                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
          }
        }
      }

      ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
  
      ActivityOptions options = ActivityOptions.fromBundle(bOptions);
      ActivityStackSupervisor.ActivityContainer container =
          (ActivityStackSupervisor.ActivityContainer)iContainer;
  
      synchronized (mService) {
        if (container != null && container.mParentActivity != null &&
            container.mParentActivity.state != RESUMED) {
          // Cannot start a child activity if the parent is not resumed.
          return ActivityManager.START_CANCELED;
        }
        final int realCallingPid = Binder.getCallingPid();
        final int realCallingUid = Binder.getCallingUid();
        int callingPid;
        if (callingUid >= 0) {
          callingPid = -1;
        } else if (caller == null) {
          callingPid = realCallingPid;
          callingUid = realCallingUid;
        } else {
          callingPid = callingUid = -1;
        }
  
        final ActivityStack stack;
        if (container == null || container.mStack.isOnHomeDisplay()) {
          stack = mSupervisor.mFocusedStack;
        } else {
          stack = container.mStack;
        }
        stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
  
        final long origId = Binder.clearCallingIdentity();
  
        
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        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);
  
        Binder.restoreCallingIdentity(origId);
        if (stack.mConfigWillChange) {
          mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
              "updateConfiguration()");
          stack.mConfigWillChange = false;
          mService.updateConfigurationLocked(config, null, false);
        }
  
        if (outResult != null) {
          outResult.result = res;
          if (res == ActivityManager.START_SUCCESS) {
            mSupervisor.mWaitingActivityLaunched.add(outResult);
            do {
              try {
                mService.wait();
              } catch (InterruptedException e) {
              }
            } while (outResult.result != START_TASK_TO_FRONT
                && !outResult.timeout && outResult.who == null);
            if (outResult.result == START_TASK_TO_FRONT) {
              res = START_TASK_TO_FRONT;
            }
          if (res == START_TASK_TO_FRONT) {
            ActivityRecord r = stack.topRunningActivityLocked();
            if (r.nowVisible && r.state == RESUMED) {
              outResult.timeout = false;
              outResult.who = new ComponentName(r.info.packageName, r.info.name);
              outResult.totalTime = 0;
              outResult.thisTime = 0;
            } else {
              outResult.thisTime = SystemClock.uptimeMillis();
              mSupervisor.mWaitingActivityVisible.add(outResult);
              do {
                try {
                  mService.wait();
                } catch (InterruptedException e) {
                }
              } while (!outResult.timeout && outResult.who == null);
            }
          }
        }
  
        final ActivityRecord launchedActivity = mReusedActivity != null
            ? mReusedActivity : outRecord[0];
        mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
        return res;
      }
    }

 

一步步分析,

1、fd安全检查

if (intent != null && intent.hasFileDescriptors()) {
  throw new IllegalArgumentException("File descriptors passed in Intent");
}

 

这里面检查intent是否有文件描述符,有的话抛异常。

2、获取信息

ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

 

后面一串主要是获取 ResolveInfo和ActivityInfo。

3、堆栈的config改变

stack = mSupervisor.mFocusedStack;
  if (stack.mConfigWillChange) {
...
          mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
              "updateConfiguration()");
          stack.mConfigWillChange = false;
...
          mService.updateConfigurationLocked(config, null, false);
        }

 

4、startActivityLocked

这个是主要的启动函数,后面文章会分析。

5、关于outResult和等待

if (outResult != null) {
  outResult.result = res;
  if (res == ActivityManager.START_SUCCESS) {
    mSupervisor.mWaitingActivityLaunched.add(outResult);
    do {
      try {
        mService.wait();
      } catch (InterruptedException e) {
      }
    } while (outResult.result != START_TASK_TO_FRONT
        && !outResult.timeout && outResult.who == null);
    if (outResult.result == START_TASK_TO_FRONT) {
      res = START_TASK_TO_FRONT;
    }
  }
  
  
  if (res == START_TASK_TO_FRONT) {
    ActivityRecord r = stack.topRunningActivityLocked();
    if (r.nowVisible && r.state == RESUMED) {
      outResult.timeout = false;
      outResult.who = new ComponentName(r.info.packageName, r.info.name);
      outResult.totalTime = 0;
      outResult.thisTime = 0;
    } else {
      outResult.thisTime = SystemClock.uptimeMillis();
      mSupervisor.mWaitingActivityVisible.add(outResult);
      do {
        try {
          mService.wait();
        } catch (InterruptedException e) {
        }
      } while (!outResult.timeout && outResult.who == null);
    }
  }
}

 

如果设置了outResult,分两步:

1、res == ActivityManager.START_SUCCESS 启动Activity成功了,等待mSupervisor.mWaitingActivityLaunched.add(outResult);

等待启动的时间,mWaitingActivityLaunched加入进去了。

后面文章我们会看到,Activity启动后,会过来设置这个值,并notifyall,去除这个等待。

2、res = START_TASK_TO_FRONT;

如果进一步结果告诉我,这个activity在前台了,等待mSupervisor.mWaitingActivityVisible.add(outResult);,

也就是等待Activity绘制完成显示的时候,这里mWaitingActivityVisible加入进去。

后面文章我们会看到,当Activity绘制完成后WMS会返回来告诉我们,并notifyall,去除这个等待。

整个startActivityMayWait分析完成了,我们将进入startActivityLocked。

Android app启动流程:调用startProcessLocked的几种情况(1)

Android app启动流程:startProcessLocked函数分析(2)

Android app启动流程:Process.start(3)

Android app启动流程:startservice(4)

Android app启动流程:broadcast广播的注册(5)

Android app启动流程:广播的发送broadcastIntentLocked(6)

Android app启动流程:广播的发送scheduleBroadcastsLocked(7)

Android app启动流程:广播的发送processNextBroadcast(8)

Android app启动流程:关于FocusedStack的研究(9)

Android app启动流程:startActivityMayWait分析(10)

Android app启动流程:startActivityLocked分析(11)

Android app启动流程:Ams对activitystack和task的管理(12)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: