当前位置:   article > 正文

Android6.0 AMS启动Activity(二) 启动进程然后启动Activity_am 启动 activity category.launcher

am 启动 activity category.launcher

在上篇博客中说到有两种方式启动进程,其中一种就是点击Launcher界面,在点击Launcher最后也会调用Activity的startActivity方法,但是在Launcher中会调用如下代码:

  1. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  

这句代码代表启动这个Activity的时候要新建一个Task,主要在AMS中所有的Activity都是保存在Task中。

我们再来看一般的Activity的主Activity其AndroidManifest.xml文件

  1. <activity android:name=".MainActivity"      
  2.       android:label="@string/app_name">      
  3.        <intent-filter>      
  4.         <action android:name="android.intent.action.MAIN" />      
  5.         <category android:name="android.intent.category.LAUNCHER" />      
  6.     </intent-filter>      
  7. </activity>      

  因此,这里的intent包含的信息为:action = "Android.intent.action.Main",category="android.intent.category.LAUNCHER"。

然后我们继续分析,Activity的startActivity函数,最终会到AMS的startActivity函数,这中间的过程就不分析了,在之前的博客中分析过。我们来看AMS的startActivity函数,最终是在ActivityStackSupervisor的startActivityMayWait函数中。

  1. @Override  
  2. public final int startActivity(IApplicationThread caller, String callingPackage,  
  3.         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,  
  4.         int startFlags, ProfilerInfo profilerInfo, Bundle options) {  
  5.     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,  
  6.         resultWho, requestCode, startFlags, profilerInfo, options,  
  7.         UserHandle.getCallingUserId());  
  8. }  
  9.   
  10. @Override  
  11. public final int startActivityAsUser(IApplicationThread caller, String callingPackage,  
  12.         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,  
  13.         int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {  
  14.     enforceNotIsolatedCaller("startActivity");  
  15.     userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,  
  16.             false, ALLOW_FULL_ONLY, "startActivity", null);  
  17.     // TODO: Switch to user app stacks here.  
  18.     return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,  
  19.             resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,  
  20.             profilerInfo, null, null, options, false, userId, null, null);  
  21. }  

我们来看下ActivityStackSupervisor的startActivityMayWait函数,先是主要调用了resolveActivity函数来解析intent的数据,也就是之前AndroidManifest.xml里的内容。

  1. ActivityInfo aInfo =  
  2.         resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);  

我们来看下resolveActivity函数主要还是通过PKMS来解析Intent,并且也设置了Intent的Component。

  1. ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,  
  2.         ProfilerInfo profilerInfo, int userId) {  
  3.     // Collect information about the target of the Intent.  
  4.     ActivityInfo aInfo;  
  5.     try {  
  6.         ResolveInfo rInfo =  
  7.             AppGlobals.getPackageManager().resolveIntent(  
  8.                     intent, resolvedType,  
  9.                     PackageManager.MATCH_DEFAULT_ONLY  
  10.                                 | ActivityManagerService.STOCK_PM_FLAGS, userId);  
  11.         aInfo = rInfo != null ? rInfo.activityInfo : null;  
  12.     } catch (RemoteException e) {  
  13.         aInfo = null;  
  14.     }  
  15.   
  16.     if (aInfo != null) {  
  17.         // Store the found target back into the intent, because now that  
  18.         // we have it we never want to do this again.  For example, if the  
  19.         // user navigates back to this point in the history, we should  
  20.         // always restart the exact same activity.  
  21.         intent.setComponent(new ComponentName(  
  22.                 aInfo.applicationInfo.packageName, aInfo.name));  
  23.   
  24.         // Don't debug things in the system process  
  25.         if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {  
  26.             if (!aInfo.processName.equals("system")) {  
  27.                 mService.setDebugApp(aInfo.processName, truefalse);  
  28.             }  
  29.         }  
  30.   
  31.         if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {  
  32.             if (!aInfo.processName.equals("system")) {  
  33.                 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);  
  34.             }  
  35.         }  
  36.   
  37.         if (profilerInfo != null) {  
  38.             if (!aInfo.processName.equals("system")) {  
  39.                 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);  
  40.             }  
  41.         }  
  42.     }  
  43.     return aInfo;  
  44. }  

后面又调用了ActivityStackSupervisor的startActivityLocked函数,在这个函数中主要创建了ActivityRecord对象
下面我们继续startActivityUncheckedLocked方法,我们先看下面这段代码,由于这个intent的标志值的位Intent.FLAG_ACTIVITY_NEW_TASK被置位,而且Intent.FLAG_ACTIVITY_MULTIPLE_TASK没有置位,因此,下面的if语句会被执行。

  1. if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&  
  2.         (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)  
  3.         || launchSingleInstance || launchSingleTask) {  
  4.     // If bring to front is requested, and no result is requested and we have not  
  5.     // been given an explicit task to launch in to, and  
  6.     // we can find a task that was started with this same  
  7.     // component, then instead of launching bring that one to the front.  
  8.     if (inTask == null && r.resultTo == null) {  
  9.         // See if there is a task to bring to the front.  If this is  
  10.         // a SINGLE_INSTANCE activity, there can be one and only one  
  11.         // instance of it in the history, and it is always in its own  
  12.         // unique task, so we do a special search.  
  13.         ActivityRecord intentActivity = !launchSingleInstance ?  
  14.                 findTaskLocked(r) : findActivityLocked(intent, r.info);  
  15.         if (intentActivity != null) {  

这段代码的逻辑是查看一下,当前有没有Task可以用来执行这个Activity。由于r.launchMode的值不为ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过findTaskLocked函数来查找存不存这样的Task,这里返回的结果是null,即taskTop为null,因此,需要创建一个新的Task来启动这个Activity。
        接着往下看:

  1. if (r.packageName != null) {  
  2.            // If the activity being launched is the same as the one currently  
  3.            // at the top, then we need to check if it should only be launched  
  4.            // once.  
  5.            ActivityStack topStack = mFocusedStack;  
  6.            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);  
  7.            if (top != null && r.resultTo == null) {  
  8.                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {  
  9.                    if (top.app != null && top.app.thread != null) {  
  10.                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0  
  11.                            || launchSingleTop || launchSingleTask) {  
  12.                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,  
  13.                                    top.task);  
  14.                            // For paranoia, make sure we have correctly  
  15.                            // resumed the top activity.  
  16.                            topStack.mLastPausedActivity = null;  
  17.                            if (doResume) {  
  18.                                resumeTopActivitiesLocked();  
  19.                            }  
  20.                            ActivityOptions.abort(options);  
  21.                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {  
  22.                                // We don't need to start a new activity, and  
  23.                                // the client said not to do anything if that  
  24.                                // is the case, so this is it!  
  25.                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;  
  26.                            }  
  27.                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);  
  28.                            return ActivityManager.START_DELIVERED_TO_TOP;  
  29.                        }  
  30.                    }  
  31.                }  
  32.            }  

这段代码的逻辑是看一下,当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,因此,这里不用进一步处理上述介绍的情况。
       执行到这里,我们知道,要在一个新的Task里面来启动这个Activity了,于是新创建一个Task,并且将这个Task设置为ActivityRecord的task成员变量

  1. if (r.resultTo == null && inTask == null && !addingToTask  
  2.         && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {  
  3.     newTask = true;//新建一个task  
  4.     targetStack = computeStackFocus(r, newTask);  
  5.     targetStack.moveToFront("startingNewTask");  
  6.   
  7.     if (reuseTask == null) {  
  8.         r.setTask(targetStack.createTaskRecord(getNextTaskId(),  
  9.                 newTaskInfo != null ? newTaskInfo : r.info,  
  10.                 newTaskIntent != null ? newTaskIntent : intent,  
  11.                 voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),  
  12.                 taskToAffiliate);  
  13.         if (DEBUG_TASKS) Slog.v(TAG_TASKS,  
  14.                 "Starting new activity " + r + " in new task " + r.task);  
  15.     }  
调用了ActivityStatck来创建一个Task,并且在这个函数中调用了addTask函数
  1. TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,  
  2.         IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,  
  3.         boolean toTop) {  
  4.     TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,  
  5.             voiceInteractor);  
  6.     addTask(task, toTop, false);  
  7.     return task;  
  8. }  

addTask函数也将这个task放入mTaskHistory一个合适的位置。

  1. void addTask(final TaskRecord task, final boolean toTop, boolean moving) {  
  2.     task.stack = this;  
  3.     if (toTop) {  
  4.         insertTaskAtTop(task, null);  
  5.     } else {  
  6.         mTaskHistory.add(0, task);  
  7.         updateTaskMovement(task, false);  
  8.     }  
  9.     if (!moving && task.voiceSession != null) {  
  10.         try {  
  11.             task.voiceSession.taskStarted(task.intent, task.taskId);  
  12.         } catch (RemoteException e) {  
  13.         }  
  14.     }  
  15. }  

下面继续调用了ActivityStack的startActivityLocked函数,在这个函数最后有如下代码,当然这个doResume为true。

  1. if (doResume) {  
  2.     mStackSupervisor.resumeTopActivitiesLocked(this, r, options);  
  3. }  
然后又回到ActivityStackSupervisor类,调用了其resumeTopActivitiesLocked方法。最后会调用resumeTopActivityInnerLocked函数,我们直接看这个函数:
  1. final ActivityRecord next = topRunningActivityLocked(null);  

先获取了下个ActivityRecord,这里也就是我们要启动的Activity。

然后会调用startPausingLocked,把当前的Activity pause。注意这里调用了startPausingLocked之前就return了。

  1. if (mResumedActivity != null) {  
  2.     if (DEBUG_STATES) Slog.d(TAG_STATES,  
  3.             "resumeTopActivityLocked: Pausing " + mResumedActivity);  
  4.     pausing |= startPausingLocked(userLeaving, falsetrue, dontWaitForPause);  
  5. }  
  6. if (pausing) {  
  7.     if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,  
  8.             "resumeTopActivityLocked: Skip resume: need to start pausing");  
  9.     // At this point we want to put the upcoming activity's process  
  10.     // at the top of the LRU list, since we know we will be needing it  
  11.     // very soon and it would be a waste to let it get killed if it  
  12.     // happens to be sitting towards the end.  
  13.     if (next.app != null && next.app.thread != null) {  
  14.         mService.updateLruProcessLocked(next.app, true, null);  
  15.     }  
  16.     if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();  
  17.     return true;  
  18. }  

我们再来看startPausingLocked函数,在startPausingLocked函数中调用了ActivityThread的schedulePauseActivity函数:

  1. final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,  
  2.         boolean dontWait) {  
  3.         ......  
  4.                         prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,  
  5.                     userLeaving, prev.configChangeFlags, dontWait);  
  6.         ......  

在ActivityThread中最后调用handlePauseActivity函数来处理,在handlePauseActivity函数中调用performPauseActivity函数最后会调用Activity的onPause方法,在这个函数最后调用了AMS的activityPaused方法。

  1. private void handlePauseActivity(IBinder token, boolean finished,  
  2.         boolean userLeaving, int configChanges, boolean dontReport) {  
  3.     ActivityClientRecord r = mActivities.get(token);  
  4.     if (r != null) {  
  5.         Slog.d(TAG, "userLeaving=" + userLeaving + " handling pause of " + r + ",isPreHoney" + r.isPreHoneycomb() +  
  6.                 "dontReport :"+  dontReport);  
  7.         if (userLeaving) {  
  8.             performUserLeavingActivity(r);  
  9.         }  
  10.   
  11.         r.activity.mConfigChangeFlags |= configChanges;  
  12.         performPauseActivity(token, finished, r.isPreHoneycomb());  
  13.         EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),  
  14.                 r.activity.getComponentName().getClassName() + ",performPauseActivity ok done.");  
  15.         Slog.d(TAG, "performPauseActivity after");  
  16.         // Make sure any pending writes are now committed.  
  17.         if (r.isPreHoneycomb()) {  
  18.             QueuedWork.waitToFinish();  
  19.         }  
  20.   
  21.         // Tell the activity manager we have paused.  
  22.         if (!dontReport) {  
  23.             try {  
  24.                 ActivityManagerNative.getDefault().activityPaused(token);  
  25.             } catch (RemoteException ex) {  
  26.                 Slog.e(TAG,"handlePauseActivity RemoteException: " + ex);  
  27.             }  
  28.         }  
  29.         EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),  
  30.                 r.activity.getComponentName().getClassName() + ",ActivityManager activityPaused ok done.");  
  31.         mSomeActivitiesChanged = true;  
  32.     }  
  33. }  
最后通过AMS的activityPausedLocked方法,又调用了ActivityStack的activityPausedLocked方法,然后调用了completePauseLocked方法,最后又到了ActivityStackSupervisor的resumeTopActivitiesLocked方法,于是又回到了resumeTopActivityInnerLocked方法,在这个函数最后又如下代码:这个时候我们要启动的Activity的进程还没启动,所以其app和app.thread为null。
  1. ActivityStack lastStack = mStackSupervisor.getLastStack();  
  2. if (next.app != null && next.app.thread != null) {  
  3.     ......  
  4.   
  5. else {  
  6.     EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, "ActivityStack resumeTopActivityInnerLock startSpecificActivityLocked fork process");  
  7.     // Whoops, need to restart this activity!  
  8.     if (!next.hasBeenLaunched) {  
  9.         next.hasBeenLaunched = true;  
  10.     } else {  
  11.         if (SHOW_APP_STARTING_PREVIEW) {  
  12.             mWindowManager.setAppStartingWindow(  
  13.                     next.appToken, next.packageName, next.theme,  
  14.                     mService.compatibilityInfoForPackageLocked(  
  15.                             next.info.applicationInfo),  
  16.                     next.nonLocalizedLabel,  
  17.                     next.labelRes, next.icon, next.logo, next.windowFlags,  
  18.                     null, true);  
  19.         }  
  20.         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);  
  21.     }  
  22.     if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);  
  23.     mStackSupervisor.startSpecificActivityLocked(next, truetrue);  
  24. }  
所以最后到了ActivityStackSupervisor的startSpecificActivityLocked函数,这个函数如果当前Activity的进程没有,会调用AMS的startProcessLocked函数
  1. void startSpecificActivityLocked(ActivityRecord r,  
  2.         boolean andResume, boolean checkConfig) {  
  3.     // Is this activity's application already running?  
  4.     ProcessRecord app = mService.getProcessRecordLocked(r.processName,  
  5.             r.info.applicationInfo.uid, true);  
  6.   
  7.     r.task.stack.setLaunchTime(r);  
  8.   
  9.     if (app != null && app.thread != null) {  
  10.         try {  
  11.             if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0  
  12.                     || !"android".equals(r.info.packageName)) {  
  13.                 // Don't add this if it is a platform component that is marked  
  14.                 // to run in multiple processes, because this is actually  
  15.                 // part of the framework so doesn't make sense to track as a  
  16.                 // separate apk in the process.  
  17.                 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,  
  18.                         mService.mProcessStats);  
  19.             }  
  20.             realStartActivityLocked(r, app, andResume, checkConfig);  
  21.             return;  
  22.         } catch (RemoteException e) {  
  23.             Slog.w(TAG, "Exception when starting activity "  
  24.                     + r.intent.getComponent().flattenToShortString(), e);  
  25.         }  
  26.   
  27.         // If a dead object exception was thrown -- fall through to  
  28.         // restart the application.  
  29.     }  
  30.   
  31.     mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,  
  32.             "activity", r.intent.getComponent(), falsefalsetrue);  
  33. }  
最后会在startProcessLocked中创建进程,然后直接到ActivityThread的main函数。这里的过程就不分析,然后在ActivityThread的main函数调用了AMS的attachApplication函数。在attachApplicationLocked中创建了一个ProcessRecord对象,调用了ActivityThread的bindApplication来完成进程的一些初始化工作。然后又调用了ActivityStackSupervisor的attachApplicationLocked函数,在这个函数又调用了realStartActivityLocked函数,然后在这个函数调用了app.thread.scheduleLaunchActivity函数,就到ActivityThread的scheduleLaunchActivity函数了,下面我们在之前博客分析过了就不分析了。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/319839
推荐阅读
相关标签
  

闽ICP备14008679号