app从启动到画出来整个流程,这一系列文档是针对这个做的笔记,可能有点乱,有不准确的地方,还请指正!

 

通过点击桌面图标,可以启动这个应用程序制定的一个Activity,后面会调用到ActivityManagerService的StartActivity的函数。经过一些判断和准备,如果顺利,AMS最终尝试启动制定的Activity,Android规定,在新的Activity启动前,原先处于resumed状态的activity会被pause。将一个activity置为pause,是通过这个activity所属进程的ApplicationThread中方法schedulePauseActivity完成的,applicationThread是应用程序跟AMS通信的一个Binder通道,在主线程ActivityThread中。

         当收到pause请求后,这个进程ActivityThread主线程会进一步处理,出来调用Activity.onPause()等方法外,还会通知WindowManagerService,因为这会引起界面发生变化。然后,进程会通知AMS它的pause请求已经完成了,可以让AMS接着执行startActivity的操作。

         如果要启动的Activity所属进程不存在,AMS还要先把进程叫起来,这是有Process.start实现的,通过参数启动应用程序的主线程ActivityThread,调用主线程的main函数。主线程启动做好初始化后,会调用attachApplication通知AMS,然后AMS会查看是否有顶层可见的Activity在等待这个进程来启动,如果有,AMS通过ApplicationThread.scheduleLaunchActivity请求应用进程启动这个activity,之后的工作就是应用进程来主导完成,activity的生命周期的调用,创建window,遍历view树等。

         结合源码解析启动过程。

第一阶段、framework侧的处理

         startActivity@ContextImpl.java–>到工具类:execStartActivity@Instrumentation.javaà到AMS:startActivity@ActivityManagerService.java。

         其中AMS对象的获取是通过ActivityManagerNative的函数gDefault这个单例对象实现的,这里就涉及进程间通讯了,其中ActivityManagerProxy是AMS在应用进程端的代表,AMS的真正实现在ActivityManagerNative中,

/*ActivityManagerNative.java*/
   static public IActivityManager getDefault() { // IActivityManager是AMS的接口类
       return gDefault.get();
}
//这是获取AMS对象的地方,因为AMS是实名的binderServer,在Servicemanager中有注册,可以通过ServiceManager.getService("activity")来查找。
    private staticfinal Singleton<IActivityManager> gDefault = newSingleton<IActivityManager>() {
       protected IActivityManager create() {
           IBinder b = ServiceManager.getService("activity");
           IActivityManager am = asInterface(b);
           return am;//这里返回的实际是ActivityManagerProxy
       }
   };
}

ActivityManagerNative的作用之一是方便客户端取得一个ActivityManagerProxy,另一个作用就是为AMS的实现提供便利,就是说AMS只要继承ActivityManagerNative,就可以将客户端的业务请求码与内部实现函数连接起来,Binder通信中,客户端请求码必须要跟服务端一致。

public finalclass ActivityManagerService extends ActivityManagerNative{}

//AMS果然是继承了ActivityManagerNative,直接面向应用程序的是ActivityManagerProxy,这个代理会利用Ibinder,进而使用ProcessState,IPCThreadState完成跟Binder驱动的通信,把请求传到服务端ActivityManagerService。

         接着看AMS中的代码,AMS做的工作是以多个类似的startActivity函数完成的。

/*ActivityManagerService.java*/
   public final int startActivity(IApplicationThread caller, StringcallingPackage,
            Intentintent, String resolvedType, IBinder resultTo, String resultWho, intrequestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
       return startActivityAsUser(caller, callingPackage, intent, resolvedType,resultTo,
                resultWho, requestCode,startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }
         UserHandle.getCallingUserId()表示调用者的用户ID。函数参数太长省略了。
public finalint startActivityAsUser(){
//检查调用者是否属于被隔离的对象
                   enforceNotIsolatedCaller("startActivity");
//检查调用者是否有权限执行这个操作
                   userId =mUserController.handleIncomingUser();
                   mActivityStarter.startActivityMayWait();
}        
/*ActivityStarter.java*/
final intstartActivityMayWait(){
//解析出符合Intent要求的目标Activity
                   ActivityInfoaInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
//判断目标Activity所属进程是不是重量级的
                   final ProcessRecord heavy =mService.mHeavyWeightProcess;
                   if (heavy != null &&(heavy.info.uid != aInfo.applicationInfo.uid
                            || !heavy.processName.equals(aInfo.processName))){}
//接着进一步调用startActivityLocked进一步做启动的工作
                   startActivityLocked();
}
//进入final intstartActivityLocked()函数
final intstartActivityLocked(){
//确保调用者进程时存在的,没有被系统kill,或者异常退出。
                   if (caller != null) {
                            callerApp =mService.getRecordForAppLocked(caller);
                            err =ActivityManager.START_PERMISSION_DENIED;}  }
//处理flag:FLAG_ACTIVITY_FORWARD_RESULT,它具有跨越式传递的作用,如Activity-1启动了Activity-2,当Activity-2启动Activity-3时用了这个标志,Activity-3调用setResult时,result不会把结果传给Activity-2,而是传给Activity-1
                   if ((launchFlags &Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0) {  
                            resultWho =sourceRecord.resultWho;
                            requestCode =sourceRecord.requestCode;
}
 
//目标Activityinfo为空,没有目标Activity处理intent,都会报错返回
         if (err ==ActivityManager.START_SUCCESS && intent.getComponent() == null)
         if (err ==ActivityManager.START_SUCCESS && aInfo == null)
//还要做两项权限检查
         boolean abort =!mSupervisor.checkStartAnyActivityPermission()
         abort |=!mService.mIntentFirewall.checkStartActivity()
                   //生成一个ActivityRecord对象,记录各项判断结果,
ActivityRecord r = new ActivityRecord();
                   //进入startActivityUnchecked(),这个函数处理跟启动模式、Intent标志相关的属性
err = startActivityUnchecked()
}
//进入startActivityUnchecked()
private intstartActivityUnchecked(){
                   //计算启动flags,计算启动的stack
                            computeLaunchingTaskFlags();
                             computeSourceStack();
                   //然后就是各种flag的处理
//START_FLAG_ONLY_IF_NEEDED,FLAG_ACTIVITY_NEW_TASK,//FLAG_ACTIVITY_CLEAR_TASK…
//最后调用ActivityStack中的startActivityLocked
         mTargetStack.startActivityLocked();
}
//进入ActivityStack中的startActivityLocked()
final void startActivityLocked(){
                   //先要看Activity是不是在新task启动,即newTask的值,如果为false,要找出Activity在那个老的task中,找到后把将它加入history中,然后把它放在stack的顶层,才能与用户交互。
                            task.addActivityToTop(r);
                            r.putInHistory();
                   //是否要执行切换动画
                            if((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0)
                   //一个Activity的界面要显示出来,在wms中必须有记录,这个记录就是apptoken,在后面添加窗口时,wms会判断如果没有这个APPtoken,就不能成功添加窗口。
                            addConfigOverride()àmWindowManager.addAppToken();
                   //是否要显示启动窗口
                            if(SHOW_APP_STARTING_PREVIEW && doShow);                           
}

到这里startActivity的判断处理流程就执行完了


简单说下AMS的功能和启动:

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();

//下面这个调用会先执行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();
	
	}