activity的启动模式,startactivity的过程

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,,onCreate
10-26 22:18:23.365 24691-24691/? D/First-Activity: recycle,,onStart
10-26 22:18:23.367 24691-24691/? D/First-Activity: recycle,,onResume

按back键,让activity的退出,activity会被出栈(Activitystack):
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onPause
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStop
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onDestroy
按home间,让activity退出,会执行onPause(),onStop(),但是不会执行onDestory(),

启动另一个activity:
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onPause
com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onCreate
com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onStart
com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onResume
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStop

从第二个activity返回:
com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onPause
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onRestart
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStart
com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onResume
com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onStop
com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onDestroy

 

1,ActivityManagerService的功能ActivityManagerService的功能

 

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

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

3)Task相关的操作removeTaskmovetasktofront。

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

 

AMS是在systemserver中启动的

SystemServer.java
	private 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.java
	public 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();
	
	}

启动时,通过Lifecycle这个Systemservice先创建ActivityManagerService实例,然后调用其start方法。

在AMS的构造函数中,会创建一个线程ServiceThread,这是一个自带消息队列的线程。

ActivityManagerService,一个用于管理Activity(其他组件)运行状态的系统进程。
AMS会向servicemanager登记多种Binderserver,如:activity,meminfo,cpuinfo,processinfo,permission等。
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.java
AMS通过ActivityStackSupervisor mStackSupervisor管理系统的Activitystack,通过StackSupervisor运行所有的activitystacks。
ActivityRecord mFocusedActivity;//当前拥有焦点的Activity。
RecentTasks mRecentTasks;//用于启动最近任务的intent列表。

ActivityStackSupervisor.java
ActivityStack mHomeStack;//包含launcher app的stack,
ActivityStack mFocusedStack;//当前可以接收输入事件或启动下一个Activity的stack。
//等待即将可见的新的Activity的列表。
ArrayList<ActivityRecord> mWaitingVisibleActivities;
//列表中的Activity可以被stop,但是要等待下一个Activity就绪。
ArrayList<ActivityRecord> mStoppingActivities
//列表中Activity可以被finish的,但是要等上一个Activity就绪。
ArrayList<ActivityRecord> mFinishingActivities 

ActivityStack.java
//所有前面Activity的回退记录,包括可能正在运行的Activity。
ArrayList<TaskRecord> mTaskHistory
//正在运行的Activity的列表,以最近的使用情况排序,第一个是最近最少使用的元素。
ArrayList<ActivityRecord> mLRUActivities
//当前正在被暂停的Activity
ActivityRecord mPausingActivity
//上一个被暂停的Activity
ActivityRecord mLastPausedActivity
//当前被恢复的Activity
ActivityRecord mResumedActivity
//最近一次被启动的Activity
ActivityRecord mLastStartedActivity

TaskRecord.java
//task中的所有的Activity,这个task是在历史记录中按顺序排列的
ArrayList<ActivityRecord> mActivities;
//当前的stack,管理者这个task中的Activity。
ActivityStack stack;

ActivityRecord.java
//表明这个Activity所属的task,
TaskRecord task; 
大致结构:
mStackSupervisor(ActivityStackSupervisor)负责管理所有的Activitystack。
ActivityStack管理着系统中的task,也就是TaskRecord。
TaskRecord中的mActivities中保存了属于当前task的Activitys(ActivityRecord),这些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;
		}
	}
}

因为Task是有先后之分的,所以对ActivityRecord的存储使用的是stack栈的方式,具体可以参考addActivityAtBottom()@TaskRecord.java,addActivityToTop()@TaskRecord.java

3,startActivity的过程
直接从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();
//如果被启动的对象和调用者是同一个,什么都不用做,只要正确恢复顶层的Activity。
	if ((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);
	}
//接着调用另一个startActivityLocked。
	mTargetStack.startActivityLocked(mStartActivity, newTask, 
		mKeepCurTransition, mOptions);
//恢复最上层的Activity。
	mSupervisor.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回调AMS,
private 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值