activity的启动模式,startactivity的过程

来源:互联网 发布:广场舞视频下载软件 编辑:程序博客网 时间:2024/05/23 11:54

Android:launchMode

      用于指定Activity被启动的方式,主要包括两个方面:即Activity是否为单实例,及Activity归属的task。不管是那种方式,被启动的Activity都要位于Activitytask的栈顶。

      1)standard,默认状态,这种模式下Activity是多实例的,系统总是启动一个新的Activity来满足要求,即使之前已经存在这个Activity的实例;并且它归属于调用startactivity将其启动那个task(除非intent明确指明FLAG_ACTIVITY_NEW_TASK,这样就跟singleTask的启动模式是一样的)。

      2),singletop,这个跟standard模式非常类似,它也表明Activity是多实例(下面是例外的情况)的,且task的归属也一致。区别是:

      对于standard,无论何时它都会生成一个新的Activity实例;而singleTop当遇到目标Activity已经存在与目标task的栈顶时,会将Intent通过onNewIntent传给这个Activity而不是生成一个新的实例。

      3),singleTask,它表明这个Activity是单实例的,Intent将通过OnNewIntent传送给已有的实例;而且他总是在一个新的task中启动。这种类型的Activity永远在task的根位置。另外,singleTask允许其他的Activity进驻到它所在的task中,这一点跟singleInstance不同。

      4),singleInstance,和singleTask基本一致,不过它不允许其他的Activity进驻到它所属的task中,也就是说,singleInstance永远都是在一个孤立的task中。

 

     

Activity的生命周期一个activity的启动:10-26 22:18:23.365 24691-24691/? D/First-Activity: recycle,,onCreate10-26 22:18:23.365 24691-24691/? D/First-Activity: recycle,,onStart10-26 22:18:23.367 24691-24691/? D/First-Activity: recycle,,onResumeback键,让activity的退出:com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onPausecom.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStopcom.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onDestroy启动另一个activitycom.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onPausecom.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onCreatecom.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onStartcom.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onResumecom.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStop从第二个activity返回:com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onPausecom.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onRestartcom.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStartcom.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onResumecom.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onStopcom.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onDestroy

 

1ActivityManagerService的功能

1)组件状态的管理,四个组件的开启、关闭等一系列操作

2)组件状态查询,查询组件当前的运行情况

3Task相关的操作removeTaskmovetasktofront

4)其他一些系统运行信息的查询getMemeoryInfo


AMS是在systemserver中启动的

SystemServer.javaprivate void startBootstrapServices() {//这里会调用AMS的start方法。mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();//然后,进行初始化,并把一些服务添加到serviceManager中。mActivityManagerService.initPowerManagement();mActivityManagerService.setSystemProcess();mActivityManagerService.installSystemProviders();mActivityManagerService.setWindowManager(wm);mActivityManagerService.enterSafeMode();//将一系列与进程管理相关的服务,注册到systemmanager。mActivityManagerService.setSystemProcess();//下面这个调用会先执行AMS中的systemready方法,确保AMS启动ok了,才会执行这个回调,在这个回调中,systemserver接着执行系统服务的启动,在这里启动systemUI。mActivityManagerService.systemReady(new Runnable() {public void run() {mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);mActivityManagerService.startObservingNativeCrashes();startSystemUi(context);mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);}});}

ActivityManagerService.javapublic void systemReady(final Runnable goingCallback) {//在AMS启动完成之前, mSystemReady是false的,synchronized(this) {if (mSystemReady) {goingCallback.run();return;}mSystemReady = true;}//下面是AMS的启动操作,包括启动home应用程序。retrieveSettings();readGrantedUriPermissionsLocked();…//这里去执行systemserver中的回调,继续systemserver中未完成的系统服务的启动。因为systemserver的后续运行要依赖AMS,所以在AMS还没就绪的情况下就冒然返回,可能造成系统宕机。if (goingCallback != null) goingCallback.run();...startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);startHomeActivityLocked(currentUserId, "systemReady");mStackSupervisor.resumeFocusedStackTopActivityLocked();}

ActivityManagerService,一个用于管理Activity(其他组件)运行状态的系统进程。AMS会向servicemanager登记多种Binderserver,如:activitymeminfcpuinfoprocessinfopermission等。
public void setSystemProcess() @ActivityManagerService.java{ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);ServiceManager.addService("meminfo", new MemBinder(this));ServiceManager.addService("cpuinfo", new CpuBinder(this));ServiceManager.addService("processinfo", new ProcessInfoService(this));ServiceManager.addService("permission", new PermissionController(this));}

2,管理当前系统中的Activity状态。Activitystack是管理系统中所有Activity状态的一个数据结构。一个Activity所经历的状态有:enum ActivityState {    INITIALIZING,//正在初始化    RESUMED,//恢复    PAUSING,//正在暂停    PAUSED,//已经暂停    STOPPING,//正在停止    STOPPED,//已经停止    FINISHING,//正在完成    DESTROYING,//正在销毁    DESTROYED//已经销毁}
Activity的状态迁移图:

 

2.1 AMS主要的变量ActivityManagerService.javaAMS通过ActivityStackSupervisor mStackSupervisor管理系统的ActivitystackActivityRecord mFocusedActivity;//当前拥有焦点的ActivityRecentTasks mRecentTasks;//用于启动最近任务的intent列表。ActivityStackSupervisor.javaActivityStack mHomeStack;//包含launcher appstackActivityStack mFocusedStack;//当前可以接收输入事件或启动下一个Activitystack//等待即将可见的新的Activity的列表。ArrayList<ActivityRecord> mWaitingVisibleActivities//列表中的Activity可以被stop,但是要等待下一个Activity就绪。ArrayList<ActivityRecord> mStoppingActivities//列表中Activity可以被finish的,但是要等上一个Activity就绪。ArrayList<ActivityRecord> mFinishingActivities ActivityStack.java//所有前面Activity的回退记录,包括可能正在运行的ActivityArrayList<TaskRecord> mTaskHistory//正在运行的Activity的列表,以最近的使用情况排序,第一个是最近最少使用的元素。ArrayList<ActivityRecord> mLRUActivities//当前正在被暂停的ActivityActivityRecord mPausingActivity//上一个被暂停的ActivityActivityRecord mLastPausedActivity//当前被恢复的ActivityActivityRecord mResumedActivity//最近一次被启动的ActivityActivityRecord mLastStartedActivityTaskRecord.java//task中的所有的Activity,这个task是在历史记录中按顺序排列的ArrayList<ActivityRecord> mActivities;//当前的stack,管理者这个task中的ActivityActivityStack stack;ActivityRecord.java//表明这个Activity所属的taskTaskRecord task; 
大致结构:mStackSupervisorActivityStackSupervisor)负责管理所有的ActivitystackActivityStack管理着系统中的task,也就是TaskRecordTaskRecord也就是Activitytask中保存了属于当前taskActivitysActivityRecord),这些Activity在是以stack的形式存放的,每一个Activity就是一个Activityrecord从获取顶层Activity的函数可以看出以上关系:
final ActivityRecord topRunningActivityLocked()@ActivityStack.java{for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();}}ActivityRecord topRunningActivityLocked()@TaskRecord.java{for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {ActivityRecord r = mActivities.get(activityNdx);if (!r.finishing && stack.okToShowLocked(r)) {return r;}}}

3startActivity的过程直接从AMS说起:
public final int startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int      requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,UserHandle.getCallingUserId());}

通过UserHandle.getCallingUserId()获取调用者的用户ID//下面主要权限检查
public final int startActivityAsUser(...){//调用者是否属于被隔离的对象。enforceNotIsolatedCaller("startActivity");//调用者是否有权限执行这一操作。userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),userId, false, ALLOW_FULL_ONLY, "startActivity", null);return mActivityStarter.startActivityMayWait(…);}

final int startActivityMayWait(...)@ActivityStarter.java{//通过解析intent,确定目标Activity。ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);//判断目标Activity所属进程,是不是重量级进程,对于重量级进程不参与正常的应用程序的生命周期。所以如果系统中已经存在的重量级进程不是即将要启动的这个,那么要给intent重新赋值,重新解析。if (aInfo.applicationInfo.privateFlags& ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0)if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {final ProcessRecord heavy = mService.mHeavyWeightProcess;if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid|| !heavy.processName.equals(aInfo.processName))) {Intent newIntent = new Intent();newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,new IntentSender(target));newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,aInfo.packageName);newIntent.setClassName("android",HeavyWeightSwitcherActivity.class.getName());intent = newIntent;rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);}}//调用 startActivityLocked进一步执行启动操作。这个 startActivityLocked函数参数较多,后面还有调用同名的 startActivityLocked函数,它的参数较少。int res = startActivityLocked(…);}

final int startActivityLocked(...)@ActivityStarter.java{//确保调用者本身的进程是存在的,否则返回 PERMISSION_DENIED,权限被拒绝错误。ProcessRecord callerApp = null;callerApp = mService.getRecordForAppLocked(caller);if (callerApp != null) {callingPid = callerApp.pid;callingUid = callerApp.info.uid;}else{err = ActivityManager.START_PERMISSION_DENIED;}//处理标记: FLAG_ACTIVITY_FORWARD_RESULT,即Activity_result的跨越式传递。if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {resultWho = sourceRecord.resultWho;}//再次多调用者做权限检查,包括是否匹配intent-filter规则。boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,requestCode, callingPid, callingUid, callingPackage,…);abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,callingPid, resolvedType, aInfo.applicationInfo);//生成一个ActivityRecord,记录各项判断结果。ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,…);//调用 startActivityUnchecked,处理启动模式,及intent标志相关的。err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,  startFlags,true, options, inTask);}

//对一系列启动标志的处理。

private int startActivityUnchecked(...){//获取intent中的启动标记。final Intent baseIntent = mInTask.getBaseIntent();mLaunchFlags = mLaunchFlags |baseIntent.getFlags();//如果被启动的对象和调用者是同一个,什么都不用做,只要正确恢复顶层的Activityif ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {resumeTargetStackIfNeeded();return START_RETURN_INTENT_TO_CALLER;}//要启动的是newtask,相关的处理。if(mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0){newTask = true;setTaskFromReuseOrCreateNewTask(taskToAffiliate);}//接着调用另一个startActivityLockedmTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);//恢复最上层的ActivitymSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);}
//这是启动Activity的最后一步了。

final void startActivityLocked(){//如果目标Activity不在新的task中启动,就要找到他属于那个已存在的task,通过遍历整个 mTaskHistory列表,如果整个task对用户还不可见,先把Activity加进去,并把它加到history队列中。addConfigOverride(r, task);这句调用是在WindowManagerservice中做好注册,也就是添加一个AppWindowToken,if (!newTask) {for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {task = mTaskHistory.get(taskNdx);if (task == r.task) {task.addActivityToTop(r);r.putInHistory();addConfigOverride(r, task);}}}//是否显示启动窗口。if (SHOW_APP_STARTING_PREVIEW && doShow) {ActivityRecord prev = r.task.topRunningActivityWithStartingWindowLocked();r.showStartingWindow(prev, showStartingIcon);}}

到这里startActivity的一系列调用就分析完了,接下来就是恢复最顶层的Activity

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions)@ActivityStackSupervisor.java {targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);result = resumeTopActivityInnerLocked(prev, options);}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {//取出最上面有效的Activity。final ActivityRecord next = topRunningActivityLocked();//next为null,启动launcher界面。if (next == null) {return isOnHomeDisplay() &&mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);}//如果正在运行的Activity就是目标对象,就不用重复启动了。if (mResumedActivity == next && next.state == ActivityState.RESUMED){return false;}//如果目标Activity正在等待停止,就是正在stoping,那么就终止这个操作,从一下列表中移除,并置sleeping标志为false。mStackSupervisor.mStoppingActivities.remove(next);mStackSupervisor.mGoingToSleepActivities.remove(next);next.sleeping = false;mStackSupervisor.mWaitingVisibleActivities.remove(next);//mResumedActivity不为null,说明前一个Activity还在运行,先执行pause操作。if (mResumedActivity != null) {pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);}//在启动新的Activity之前,要把前一个窗口隐藏掉。这个操作只在前一个Activity正在finishing时执行,这就意味着它处于正在resumed的Activity的上面,所以要把它尽快隐藏,也就是说是否要隐藏前一个取决于新的Activity是不是全屏显示。if (prev != null && prev != next) {if (prev.finishing) {mWindowManager.setAppVisibility(prev.appToken, false);}}//正式启动目标Activity,目标进程已有实例存在,告知目标线程resume制定的Activity,这个函数 scheduleResumeActivity会叫起Activity的onResume方法。if (next.app != null && next.app.thread != null) {mWindowManager.setAppVisibility(next.appToken, true);next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,mService.isNextTransitionForward(), resumeAnimOptions);}else{//目标Activity所属程序还没进程在运行,启动目标进程。mStackSupervisor.startSpecificActivityLocked(next, true, true);}}

// startSpecificActivityLocked最后会调用Process.start()启动一个进程,同时加载了 ActivityThread这一主线程。private final void startProcessLocked(...)@ActivityManagerService.java{entryPoint = "android.app.ActivityThread";Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,app.info.dataDir, entryPointArgs);}//目标进程启动后,会通过 attachApplication回调AMSprivate void attach(boolean system)@ActivityThread.java {final IActivityManager mgr = ActivityManagerNative.getDefault();mgr.attachApplication(mAppThread);}//AMS在接收回调后,会判断当前是否有Activity等待这个进程的启动,如果有,就调用 realStartActivityLocked继续之前的启动操作,接下来就是Activity生命周期的开始。private final boolean attachApplicationLocked()@ActivityManagerService.java{mStackSupervisor.attachApplicationLocked(app);}boolean attachApplicationLocked(ProcessRecord app)@ActivityStackSupervisor.java{realStartActivityLocked(hr, app, true, true);}final boolean realStartActivityLocked()@ActivityStackSupervisor.java{app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,…);}

阅读全文
0 0