AMS 深入了解(二、Activity管理)(and5.1)
2015-11-27 16:15
302 查看
这次我们讲下AMS的Activity管理,我们先从如何启动Activity说起。
再来看下startActivityForResult函数
而在Instrumentation的execStartActivity函数中调用了AMS的startActivity函数。至于AMS的startActivity函数我们后续再分析。
有时候我们调用的是context的startActivity函数,最后的是contextImpl的startActivity函数:
在contextImpl中的startActivity函数最后也是调用了Instrumentation的execStartActivity函数。
而最终都是通过binder调用AMS的startActivity函数。下面我们看下AMS的startActivity函数:
下面我们看看AMS的startActivity函数
startActivity方法中调用了ActivityStackSupervisor的startActivityMayWait函数,而在startActivityMayWait又调用了startActivityLocked函数,节选了重要代码:
startActivityUncheckedLocked函数比较长,主要是通过Intent的标志和Activity的属性来确定Activity的Task。
找到Activity的Task后,调用ActivityStack的startActivityLocked方法继续启动。
看下上面的注释,最后是调用了ActivityStackSupervisor的resumeTopActivitiesLocked函数,这个函数主要是将位于栈顶的Activity显示出来。最后会调用resumeTopActivityInnerLocked函数:
resumeTopActivitiesLocked,如果Activity的应用已经启动,就调用应用进程的scheduleResumeActivity方法,最终到应用的onResume方法,如果应用还没启动调用startSpecificActivityLocked方法。
startSpecificActivityLocked方法中,如果发现没有启动应用,就调用mService.startProcessLocked。最终会调用Process.start方法启动新进程。
而如果进程已经启动会调用realStartActivityLocked方法,这个方法中会调用app.thread.scheduleLaunchActivity函数,最终调用应用的onCreate方法。
三、ActivityThread的启动
启动应用的进程的话,会调用ActivityThread的main方法:
上面调用了ActivityThread的attach方法:
在ActivityThread中,把ApplicationThread这个Binder服务端传给AMS。
attachApplicationLocked方法,先调用了ApplicationThread的接口bindApplication,这样就到应用ApplicationThread中了。
调用完这个方法后,还会调用mStackSupervisor.attachApplicationLocked,这个方法主要调用了realStartActivityLocked,这个方法前面分析过了。这边进程已经启动,就调用
app.thread.scheduleLaunchActivity,最后调用应用的oncreate方法。
因为除了开启Activity能启动进程外,启动Service、发送广播也可能启动进程。因此、这里还要调用mServices的attachApplicationLocked,和sendPendingBroadcastsLocked来处理Service的启动、和广播的启动。
最后我们再来看看前面调用的bindApplication,最后调用了handleBindApplication方法,这个方法主要是创建应用框架中的各个对象,这里我们不再介绍。
一、应用startActivity函数
先来看看Activity的startActivity函数:public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } }
再来看下startActivityForResult函数
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); ......调用了Instrumentation的execStartActivity函数。
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); if (am.match(who, null, intent)) { am.mHits++; if (am.isBlocking()) { return requestCode >= 0 ? am.getResult() : null; } break; } } } } try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(); int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { } return null; }
而在Instrumentation的execStartActivity函数中调用了AMS的startActivity函数。至于AMS的startActivity函数我们后续再分析。
有时候我们调用的是context的startActivity函数,最后的是contextImpl的startActivity函数:
public void startActivity(Intent intent, Bundle options) { warnIfCallingFromSystemProcess(); if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { throw new AndroidRuntimeException( "Calling startActivity() from outside of an Activity " + " context requires the FLAG_ACTIVITY_NEW_TASK flag." + " Is this really what you want?"); } mMainThread.getInstrumentation().execStartActivity( getOuterContext(), mMainThread.getApplicationThread(), null, (Activity)null, intent, -1, options); }
在contextImpl中的startActivity函数最后也是调用了Instrumentation的execStartActivity函数。
而最终都是通过binder调用AMS的startActivity函数。下面我们看下AMS的startActivity函数:
二、AMS的startActivity函数
下面我们看看AMS的startActivity函数public int startActivity(IBinder whoThread, String callingPackage, Intent intent, String resolvedType, Bundle options) { checkCaller(); int callingUser = UserHandle.getCallingUserId(); TaskRecord tr; IApplicationThread appThread; synchronized (ActivityManagerService.this) { tr = recentTaskForIdLocked(mTaskId); if (tr == null) { throw new IllegalArgumentException("Unable to find task ID " + mTaskId); } appThread = ApplicationThreadNative.asInterface(whoThread); if (appThread == null) { throw new IllegalArgumentException("Bad app thread " + appThread); } } return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, resolvedType, null, null, null, null, 0, 0, null, null, null, options, callingUser, null, tr); }
startActivity方法中调用了ActivityStackSupervisor的startActivityMayWait函数,而在startActivityMayWait又调用了startActivityLocked函数,节选了重要代码:
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,//新建ActivityRecord intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, this, container, options); if (outActivity != null) { outActivity[0] = r; } final ActivityStack stack = getFocusedStack(); if (voiceSession == null && (stack.mResumedActivity == null || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,//现在不能切换进程,比如在通电话 realCallingPid, realCallingUid, "Activity start")) { PendingActivityLaunch pal = new PendingActivityLaunch(r, sourceRecord, startFlags, stack); mPendingActivityLaunches.add(pal);//不Activity信息放在mPendingActivityLaunches ActivityOptions.abort(options); return ActivityManager.START_SWITCHES_CANCELED; } } if (mService.mDidAppSwitch) { // This is the second allowed switch since we stopped switches, // so now just generally allow switches. Use case: user presses // home (switches disabled, switch to home, mDidAppSwitch now true); // user taps a home icon (coming from home so allowed, we hit here // and now allow anyone to switch again). mService.mAppSwitchesAllowedTime = 0; } else { mService.mDidAppSwitch = true; } doPendingActivityLaunchesLocked(false);//启动挂起等待的Activity err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);//继续启动当前Activity
startActivityUncheckedLocked函数比较长,主要是通过Intent的标志和Activity的属性来确定Activity的Task。
找到Activity的Task后,调用ActivityStack的startActivityLocked方法继续启动。
final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume, boolean keepCurTransition, Bundle options) { TaskRecord rTask = r.task; final int taskId = rTask.taskId; if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) { // Last activity in task had been removed or ActivityManagerService is reusing task. // Insert or replace. // Might not even be in. insertTaskAtTop(rTask); mWindowManager.moveTaskToTop(taskId);//如果是新的Task,把它放在顶部 } TaskRecord task = null; if (!newTask) { // If starting in an existing task, find where that is... boolean startIt = true; for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { task = mTaskHistory.get(taskNdx); if (task.getTopActivity() == null) { // All activities in task are finishing. continue; } if (task == r.task) { if (!startIt) { task.addActivityToTop(r); r.putInHistory(); mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId, r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } ActivityOptions.abort(options); return; } break; } else if (task.numFullscreen > 0) { startIt = false; } } } if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) { mStackSupervisor.mUserLeaving = false; } task = r.task; if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task, new RuntimeException("here").fillInStackTrace()); task.addActivityToTop(r);//把Activity放在Task的顶部 task.setFrontOfTask(); r.putInHistory(); if (!isHomeStack() || numActivities() > 0) { ............//如果不是Home应用的Stack,WMS准备绘制Activity以及动画 } else { mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId, r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind); ActivityOptions.abort(options); options = null; } if (VALIDATE_TOKENS) { validateAppTokensLocked(); } if (doResume) { mStackSupervisor.resumeTopActivitiesLocked(this, r, options);//启动Activity } }
看下上面的注释,最后是调用了ActivityStackSupervisor的resumeTopActivitiesLocked函数,这个函数主要是将位于栈顶的Activity显示出来。最后会调用resumeTopActivityInnerLocked函数:
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { ............. if (next == null) {//如果当前没有Activity,显示Home Activity // There are no more activities! Let's just start up the // Launcher... ActivityOptions.abort(options); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities"); } next.delayedResume = false; if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) { //如果当前Activity就是要启动的Activity,直接返回 return false; } .............. boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0; boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause); if (mResumedActivity != null) { //暂停当前Activity pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); } if (pausing) { .........//如果系统正在暂停Activity,先退出 return true; } boolean anim = true; ......//调用WMS的方法处理Activity的显示 ActivityStack lastStack = mStackSupervisor.getLastStack(); if (next.app != null && next.app.thread != null) { //如果Activity所在的应用已经存在,把Activity显示出来 // This activity is now becoming visible. mWindowManager.setAppVisibility(next.appToken, true); ........... try { // Deliver all pending results. ArrayList<ResultInfo> a = next.results; if (a != null) { final int N = a.size(); if (!next.finishing && N > 0) { if (DEBUG_RESULTS) Slog.v( TAG, "Delivering results to " + next + ": " + a); next.app.thread.scheduleSendResult(next.appToken, a); } } if (next.newIntents != null) { next.app.thread.scheduleNewIntent(next.newIntents, next.appToken); } EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, System.identityHashCode(next), next.task.taskId, next.shortComponentName); next.sleeping = false; mService.showAskCompatModeDialogLocked(next); next.app.pendingUiClean = true; next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); next.clearOptionsLocked(); //调用onResume方法 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, mService.isNextTransitionForward(), resumeAnimOptions); mStackSupervisor.checkReadyForSleepLocked(); if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Resumed " + next); } catch (Exception e) { ......... return true; } else { .........//Activity应用进程没有,先启动进程 mStackSupervisor.startSpecificActivityLocked(next, true, true); } return true; }
resumeTopActivitiesLocked,如果Activity的应用已经启动,就调用应用进程的scheduleResumeActivity方法,最终到应用的onResume方法,如果应用还没启动调用startSpecificActivityLocked方法。
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime(r); if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) {..... } } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
startSpecificActivityLocked方法中,如果发现没有启动应用,就调用mService.startProcessLocked。最终会调用Process.start方法启动新进程。
而如果进程已经启动会调用realStartActivityLocked方法,这个方法中会调用app.thread.scheduleLaunchActivity函数,最终调用应用的onCreate方法。
三、ActivityThread的启动
启动应用的进程的话,会调用ActivityThread的main方法:public static void main(String[] args) { SamplingProfilerIntegration.start(); CloseGuard.setEnabled(false); Environment.initForCurrentUser(); EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop();//进去消息循环 throw new RuntimeException("Main thread loop unexpectedly exited"); }
上面调用了ActivityThread的attach方法:
private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) {//非系统应用 ViewRootImpl.addFirstDrawHandler(new Runnable() { @Override public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread);//调用AMS的attachApplication ......
在ActivityThread中,把ApplicationThread这个Binder服务端传给AMS。
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ............ ProfilerInfo profilerInfo = profileFile == null ? null : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,//调用应用的bindApplication接口 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked()); updateLruProcessLocked(app, false, null); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); } catch (Exception e) { .......... return false; } ...... boolean badApp = false; boolean didSomething = false; if (normalMode) { try {//处理挂起的Activity if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { badApp = true;} } // Find any services that should be running in this process... if (!badApp) { try {//处理挂起的Service didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) {badApp = true;} } if (!badApp && isPendingBroadcastProcessLocked(pid)) { try {//发起挂起的广播 didSomething |= sendPendingBroadcastsLocked(app); } catch (Exception e) {badApp = true;} } ........... return true; }
attachApplicationLocked方法,先调用了ApplicationThread的接口bindApplication,这样就到应用ApplicationThread中了。
调用完这个方法后,还会调用mStackSupervisor.attachApplicationLocked,这个方法主要调用了realStartActivityLocked,这个方法前面分析过了。这边进程已经启动,就调用
app.thread.scheduleLaunchActivity,最后调用应用的oncreate方法。
因为除了开启Activity能启动进程外,启动Service、发送广播也可能启动进程。因此、这里还要调用mServices的attachApplicationLocked,和sendPendingBroadcastsLocked来处理Service的启动、和广播的启动。
最后我们再来看看前面调用的bindApplication,最后调用了handleBindApplication方法,这个方法主要是创建应用框架中的各个对象,这里我们不再介绍。
相关文章推荐
- FileReader
- .net wifi连接的和修改IP等各项操作
- 黑马程序员—Java基础—集合
- Keil MDK C (error: #29:expected an expression)错误的解决
- python元组传参的理解
- Dapper,大规模分布式系统的跟踪系统
- size_type
- 菜鸟学Java----内部类2
- ORM之四:调用入口与调用示例
- easyUI框架之学习2--添加左侧导航栏
- [LeetCode]Shortest Word Distance
- js 数组和对象
- 轻松学习C#的异常处理
- How does the Visitor Pattern come from?如何推导出访问者模式
- 排序——基本排序算法
- OpenCV - 区域生长算法
- java 生成excel根据jxl
- 直方图均衡化原理
- codeforces 601A The Two Routes(BFS)
- jquery 设置select的默认值