AMS 深入了解(二、Activity管理)(and5.1)

转载: https://blog.csdn.net/kc58236582/article/details/50069785

这次我们讲下AMS的Activity管理,我们先从如何启动Activity说起。

一、应用startActivity函数

先来看看Activity的startActivity函数:


  
  
  1. public void startActivity(Intent intent, @Nullable Bundle options) {
  2. if (options != null) {
  3. startActivityForResult(intent, - 1, options);
  4. } else {
  5. // Note we want to go through this call for compatibility with
  6. // applications that may have overridden the method.
  7. startActivityForResult(intent, - 1);
  8. }
  9. }

再来看下startActivityForResult函数


  
  
  1. public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
  2. if (mParent == null) {
  3. Instrumentation.ActivityResult ar =
  4. mInstrumentation.execStartActivity(
  5. this, mMainThread.getApplicationThread(), mToken, this,
  6. intent, requestCode, options);
  7. ......
调用了Instrumentation的execStartActivity函数。


  
  
  1. public ActivityResult execStartActivity(
  2. Context who, IBinder contextThread, IBinder token, Activity target,
  3. Intent intent, int requestCode, Bundle options) {
  4. IApplicationThread whoThread = (IApplicationThread) contextThread;
  5. if (mActivityMonitors != null) {
  6. synchronized (mSync) {
  7. final int N = mActivityMonitors.size();
  8. for ( int i= 0; i<N; i++) {
  9. final ActivityMonitor am = mActivityMonitors.get(i);
  10. if (am.match(who, null, intent)) {
  11. am.mHits++;
  12. if (am.isBlocking()) {
  13. return requestCode >= 0 ? am.getResult() : null;
  14. }
  15. break;
  16. }
  17. }
  18. }
  19. }
  20. try {
  21. intent.migrateExtraStreamToClipData();
  22. intent.prepareToLeaveProcess();
  23. int result = ActivityManagerNative.getDefault()
  24. .startActivity(whoThread, who.getBasePackageName(), intent,
  25. intent.resolveTypeIfNeeded(who.getContentResolver()),
  26. token, target != null ? target.mEmbeddedID : null,
  27. requestCode, 0, null, options);
  28. checkStartActivityResult(result, intent);
  29. } catch (RemoteException e) {
  30. }
  31. return null;
  32. }

而在Instrumentation的execStartActivity函数中调用了AMS的startActivity函数。至于AMS的startActivity函数我们后续再分析。
有时候我们调用的是context的startActivity函数,最后的是contextImpl的startActivity函数:


  
  
  1. public void startActivity(Intent intent, Bundle options) {
  2. warnIfCallingFromSystemProcess();
  3. if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
  4. throw new AndroidRuntimeException(
  5. "Calling startActivity() from outside of an Activity "
  6. + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
  7. + " Is this really what you want?");
  8. }
  9. mMainThread.getInstrumentation().execStartActivity(
  10. getOuterContext(), mMainThread.getApplicationThread(), null,
  11. (Activity) null, intent, - 1, options);
  12. }

在contextImpl中的startActivity函数最后也是调用了Instrumentation的execStartActivity函数。

而最终都是通过binder调用AMS的startActivity函数。下面我们看下AMS的startActivity函数:


二、AMS的startActivity函数

下面我们看看AMS的startActivity函数


  
  
  1. public int startActivity(IBinder whoThread, String callingPackage,
  2. Intent intent, String resolvedType, Bundle options) {
  3. checkCaller();
  4. int callingUser = UserHandle.getCallingUserId();
  5. TaskRecord tr;
  6. IApplicationThread appThread;
  7. synchronized (ActivityManagerService. this) {
  8. tr = recentTaskForIdLocked(mTaskId);
  9. if (tr == null) {
  10. throw new IllegalArgumentException( "Unable to find task ID " + mTaskId);
  11. }
  12. appThread = ApplicationThreadNative.asInterface(whoThread);
  13. if (appThread == null) {
  14. throw new IllegalArgumentException( "Bad app thread " + appThread);
  15. }
  16. }
  17. return mStackSupervisor.startActivityMayWait(appThread, - 1, callingPackage, intent,
  18. resolvedType, null, null, null, null, 0, 0, null, null,
  19. null, options, callingUser, null, tr);
  20. }

startActivity方法中调用了ActivityStackSupervisor的startActivityMayWait函数,而在startActivityMayWait又调用了startActivityLocked函数,节选了重要代码:


  
  
  1. ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, //新建ActivityRecord
  2. intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
  3. requestCode, componentSpecified, this, container, options);
  4. if (outActivity != null) {
  5. outActivity[ 0] = r;
  6. }
  7. final ActivityStack stack = getFocusedStack();
  8. if (voiceSession == null && (stack.mResumedActivity == null
  9. || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
  10. if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, //现在不能切换进程,比如在通电话
  11. realCallingPid, realCallingUid, "Activity start")) {
  12. PendingActivityLaunch pal =
  13. new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
  14. mPendingActivityLaunches.add(pal); //不Activity信息放在mPendingActivityLaunches
  15. ActivityOptions.abort(options);
  16. return ActivityManager.START_SWITCHES_CANCELED;
  17. }
  18. }
  19. if (mService.mDidAppSwitch) {
  20. // This is the second allowed switch since we stopped switches,
  21. // so now just generally allow switches. Use case: user presses
  22. // home (switches disabled, switch to home, mDidAppSwitch now true);
  23. // user taps a home icon (coming from home so allowed, we hit here
  24. // and now allow anyone to switch again).
  25. mService.mAppSwitchesAllowedTime = 0;
  26. } else {
  27. mService.mDidAppSwitch = true;
  28. }
  29. doPendingActivityLaunchesLocked( false); //启动挂起等待的Activity
  30. err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
  31. startFlags, true, options, inTask); //继续启动当前Activity

startActivityUncheckedLocked函数比较长,主要是通过Intent的标志和Activity的属性来确定Activity的Task。

找到Activity的Task后,调用ActivityStack的startActivityLocked方法继续启动。


  
  
  1. final void startActivityLocked(ActivityRecord r, boolean newTask,
  2. boolean doResume, boolean keepCurTransition, Bundle options) {
  3. TaskRecord rTask = r.task;
  4. final int taskId = rTask.taskId;
  5. if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
  6. // Last activity in task had been removed or ActivityManagerService is reusing task.
  7. // Insert or replace.
  8. // Might not even be in.
  9. insertTaskAtTop(rTask);
  10. mWindowManager.moveTaskToTop(taskId); //如果是新的Task,把它放在顶部
  11. }
  12. TaskRecord task = null;
  13. if (!newTask) {
  14. // If starting in an existing task, find where that is...
  15. boolean startIt = true;
  16. for ( int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
  17. task = mTaskHistory.get(taskNdx);
  18. if (task.getTopActivity() == null) {
  19. // All activities in task are finishing.
  20. continue;
  21. }
  22. if (task == r.task) {
  23. if (!startIt) {
  24. task.addActivityToTop(r);
  25. r.putInHistory();
  26. mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
  27. r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
  28. (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
  29. r.userId, r.info.configChanges, task.voiceSession != null,
  30. r.mLaunchTaskBehind);
  31. if (VALIDATE_TOKENS) {
  32. validateAppTokensLocked();
  33. }
  34. ActivityOptions.abort(options);
  35. return;
  36. }
  37. break;
  38. } else if (task.numFullscreen > 0) {
  39. startIt = false;
  40. }
  41. }
  42. }
  43. if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
  44. mStackSupervisor.mUserLeaving = false;
  45. }
  46. task = r.task;
  47. if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
  48. new RuntimeException( "here").fillInStackTrace());
  49. task.addActivityToTop(r); //把Activity放在Task的顶部
  50. task.setFrontOfTask();
  51. r.putInHistory();
  52. if (!isHomeStack() || numActivities() > 0) {
  53. ............ //如果不是Home应用的Stack,WMS准备绘制Activity以及动画
  54. } else {
  55. mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
  56. r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
  57. (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
  58. r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
  59. ActivityOptions.abort(options);
  60. options = null;
  61. }
  62. if (VALIDATE_TOKENS) {
  63. validateAppTokensLocked();
  64. }
  65. if (doResume) {
  66. mStackSupervisor.resumeTopActivitiesLocked( this, r, options); //启动Activity
  67. }
  68. }

看下上面的注释,最后是调用了ActivityStackSupervisor的resumeTopActivitiesLocked函数,这个函数主要是将位于栈顶的Activity显示出来。最后会调用resumeTopActivityInnerLocked函数:


  
  
  1. final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
  2. .............
  3. if (next == null) { //如果当前没有Activity,显示Home Activity
  4. // There are no more activities! Let's just start up the
  5. // Launcher...
  6. ActivityOptions.abort(options);
  7. if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
  8. final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
  9. HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
  10. return isOnHomeDisplay() &&
  11. mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");
  12. }
  13. next.delayedResume = false;
  14. if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
  15. mStackSupervisor.allResumedActivitiesComplete()) {
  16. //如果当前Activity就是要启动的Activity,直接返回
  17. return false;
  18. }
  19. ..............
  20. boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
  21. boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
  22. if (mResumedActivity != null) {
  23. //暂停当前Activity
  24. pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
  25. }
  26. if (pausing) {
  27. ......... //如果系统正在暂停Activity,先退出
  28. return true;
  29. }
  30. boolean anim = true;
  31. ...... //调用WMS的方法处理Activity的显示
  32. ActivityStack lastStack = mStackSupervisor.getLastStack();
  33. if (next.app != null && next.app.thread != null) {
  34. //如果Activity所在的应用已经存在,把Activity显示出来
  35. // This activity is now becoming visible.
  36. mWindowManager.setAppVisibility(next.appToken, true);
  37. ...........
  38. try {
  39. // Deliver all pending results.
  40. ArrayList<ResultInfo> a = next.results;
  41. if (a != null) {
  42. final int N = a.size();
  43. if (!next.finishing && N > 0) {
  44. if (DEBUG_RESULTS) Slog.v(
  45. TAG, "Delivering results to " + next
  46. + ": " + a);
  47. next.app.thread.scheduleSendResult(next.appToken, a);
  48. }
  49. }
  50. if (next.newIntents != null) {
  51. next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
  52. }
  53. EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
  54. System.identityHashCode(next), next.task.taskId, next.shortComponentName);
  55. next.sleeping = false;
  56. mService.showAskCompatModeDialogLocked(next);
  57. next.app.pendingUiClean = true;
  58. next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
  59. next.clearOptionsLocked();
  60. //调用onResume方法
  61. next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
  62. mService.isNextTransitionForward(), resumeAnimOptions);
  63. mStackSupervisor.checkReadyForSleepLocked();
  64. if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Resumed " + next);
  65. } catch (Exception e) {
  66. .........
  67. return true;
  68. }
  69. else {
  70. ......... //Activity应用进程没有,先启动进程
  71. mStackSupervisor.startSpecificActivityLocked(next, true, true);
  72. }
  73. return true;
  74. }

resumeTopActivitiesLocked,如果Activity的应用已经启动,就调用应用进程的scheduleResumeActivity方法,最终到应用的onResume方法,如果应用还没启动调用startSpecificActivityLocked方法。


  
  
  1. void startSpecificActivityLocked(ActivityRecord r,
  2. boolean andResume, boolean checkConfig) {
  3. ProcessRecord app = mService.getProcessRecordLocked(r.processName,
  4. r.info.applicationInfo.uid, true);
  5. r.task.stack.setLaunchTime(r);
  6. if (app != null && app.thread != null) {
  7. try {
  8. if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
  9. || ! "android".equals(r.info.packageName)) {
  10. app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
  11. mService.mProcessStats);
  12. }
  13. realStartActivityLocked(r, app, andResume, checkConfig);
  14. return;
  15. } catch (RemoteException e) {.....
  16. }
  17. }
  18. mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
  19. "activity", r.intent.getComponent(), false, false, true);
  20. }

startSpecificActivityLocked方法中,如果发现没有启动应用,就调用mService.startProcessLocked。在startProcessLocked会新建一个ProcessRecord保存下来,最终会调用Process.start方法启动新进程。

而如果进程已经启动会调用realStartActivityLocked方法,这个方法中会调用app.thread.scheduleLaunchActivity函数,最终调用应用的onCreate方法。

三、ActivityThread的启动

启动应用的进程的话,会调用ActivityThread的main方法:


  
  
  1. public static void main(String[] args) {
  2. SamplingProfilerIntegration.start();
  3. CloseGuard.setEnabled( false);
  4. Environment.initForCurrentUser();
  5. EventLogger.setReporter( new EventLoggingReporter());
  6. Security.addProvider( new AndroidKeyStoreProvider());
  7. final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
  8. TrustedCertificateStore.setDefaultUserDirectory(configDir);
  9. Process.setArgV0( "<pre-initialized>");
  10. Looper.prepareMainLooper();
  11. ActivityThread thread = new ActivityThread();
  12. thread.attach( false);
  13. if (sMainThreadHandler == null) {
  14. sMainThreadHandler = thread.getHandler();
  15. }
  16. if ( false) {
  17. Looper.myLooper().setMessageLogging( new
  18. LogPrinter(Log.DEBUG, "ActivityThread"));
  19. }
  20. Looper.loop(); //进去消息循环
  21. throw new RuntimeException( "Main thread loop unexpectedly exited");
  22. }

上面调用了ActivityThread的attach方法:


  
  
  1. private void attach(boolean system) {
  2. sCurrentActivityThread = this;
  3. mSystemThread = system;
  4. if (!system) { //非系统应用
  5. ViewRootImpl.addFirstDrawHandler( new Runnable() {
  6. @Override
  7. public void run() {
  8. ensureJitEnabled();
  9. }
  10. });
  11. android.ddm.DdmHandleAppName.setAppName( "<pre-initialized>",
  12. UserHandle.myUserId());
  13. RuntimeInit.setApplicationObject(mAppThread.asBinder());
  14. final IActivityManager mgr = ActivityManagerNative.getDefault();
  15. try {
  16. mgr.attachApplication(mAppThread); //调用AMS的attachApplication
  17. ......

在ActivityThread中,把ApplicationThread这个Binder服务端传给AMS。


  
  
  1. private final boolean attachApplicationLocked(IApplicationThread thread,
  2. int pid) {
  3. ............
  4. ProfilerInfo profilerInfo = profileFile == null ? null
  5. : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
  6. thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, //调用应用的bindApplication接口
  7. profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
  8. app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
  9. isRestrictedBackupMode || !normalMode, app.persistent,
  10. new Configuration(mConfiguration), app.compat,
  11. getCommonServicesLocked(app.isolated),
  12. mCoreSettingsObserver.getCoreSettingsLocked());
  13. updateLruProcessLocked(app, false, null);
  14. app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
  15. } catch (Exception e) {
  16. ..........
  17. return false;
  18. }
  19. ......
  20. boolean badApp = false;
  21. boolean didSomething = false;
  22. if (normalMode) {
  23. try { //处理挂起的Activity
  24. if (mStackSupervisor.attachApplicationLocked(app)) {
  25. didSomething = true;
  26. }
  27. } catch (Exception e) { badApp = true;}
  28. }
  29. // Find any services that should be running in this process...
  30. if (!badApp) {
  31. try { //处理挂起的Service
  32. didSomething |= mServices.attachApplicationLocked(app, processName);
  33. } catch (Exception e) {badApp = true;}
  34. }
  35. if (!badApp && isPendingBroadcastProcessLocked(pid)) {
  36. try { //发起挂起的广播
  37. didSomething |= sendPendingBroadcastsLocked(app);
  38. } catch (Exception e) {badApp = true;}
  39. }
  40. ...........
  41. return true;
  42. }

attachApplicationLocked方法,先调用了ApplicationThread的接口bindApplication,这样就到应用ActivityThread中了,在ActivityThread在handleBindApplication中主要是初始化应用的数据。

调用完这个方法后,还会调用mStackSupervisor.attachApplicationLocked,这个方法主要调用了realStartActivityLocked,这个方法前面分析过了。这边进程已经启动,就调用

app.thread.scheduleLaunchActivity,在这个方法中创建了ActivityClientRecord。然后发送了一个消息。


  
  
  1. @ Override
  2. public final void scheduleLaunchActivity (Intent intent, IBinder token, int ident,
  3. ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
  4. CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
  5. int procState, Bundle state, PersistableBundle persistentState,
  6. List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
  7. boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
  8. updateProcessState(procState, false);
  9. ActivityClientRecord r = new ActivityClientRecord();
  10. r.token = token;
  11. r.ident = ident;
  12. r.intent = intent;
  13. r.referrer = referrer;
  14. r.voiceInteractor = voiceInteractor;
  15. r.activityInfo = info;
  16. r.compatInfo = compatInfo;
  17. r.state = state;
  18. r.persistentState = persistentState;
  19. r.pendingResults = pendingResults;
  20. r.pendingIntents = pendingNewIntents;
  21. r.startsNotResumed = notResumed;
  22. r.isForward = isForward;
  23. r.profilerInfo = profilerInfo;
  24. r.overrideConfig = overrideConfig;
  25. updatePendingConfiguration(curConfig);
  26. sendMessage(H.LAUNCH_ACTIVITY, r);
  27. }

消息处理会执行到handleLaunchActivity函数,在performLaunchActivity函数中会创建Activity,并且调用Activity的attach方法创建PhoneWindow等,在performActivity方法中会把这个ActivityClientRecord对象放到mActivities中去。我们来看下代码:


  
  
  1. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  2. ......
  3. Activity activity = null;
  4. try {
  5. java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
  6. activity = mInstrumentation.newActivity( //创建Activity
  7. cl, component.getClassName(), r.intent);
  8. StrictMode.incrementExpectedActivityCount(activity.getClass());
  9. r.intent.setExtrasClassLoader(cl);
  10. r.intent.prepareToEnterProcess();
  11. if (r.state != null) {
  12. r.state.setClassLoader(cl);
  13. }
  14. } catch (Exception e) {
  15. if (!mInstrumentation.onException(activity, e)) {
  16. throw new RuntimeException(
  17. "Unable to instantiate activity " + component
  18. + ": " + e.toString(), e);
  19. }
  20. }
  21. try {
  22. Application app = r.packageInfo.makeApplication( false, mInstrumentation);
  23. if (activity != null) {
  24. Context appContext = createBaseContextForActivity(r, activity);
  25. CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
  26. Configuration config = new Configuration(mCompatConfiguration);
  27. if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
  28. + r.activityInfo.name + " with config " + config);
  29. activity.attach(appContext, this, getInstrumentation(), r.token, //Activity的attach方法
  30. r.ident, app, r.intent, r.activityInfo, title, r.parent,
  31. r.embeddedID, r.lastNonConfigurationInstances, config,
  32. r.referrer, r.voiceInteractor);
  33. if (customIntent != null) {
  34. activity.mIntent = customIntent;
  35. }
  36. r.lastNonConfigurationInstances = null;
  37. activity.mStartedActivity = false;
  38. int theme = r.activityInfo.getThemeResource();
  39. if (theme != 0) {
  40. activity.setTheme(theme);
  41. }
  42. activity.mCalled = false;
  43. if (r.isPersistable()) {
  44. mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
  45. } else {
  46. mInstrumentation.callActivityOnCreate(activity, r.state); //调用Activity的onCreate函数
  47. }
  48. ......
  49. mActivities.put(r.token, r); //将ActivityClientRecord放入mActivities中
  50. ......








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值