App的启动过程(1)framework侧-startActivity的判断处理流程
来源:互联网 发布:淘宝怎么隐藏真实姓名 编辑:程序博客网 时间:2024/06/09 16:37
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相关的操作,removeTask,movetasktofront。
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();//下面这个调用会先执行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();}
- App的启动过程(1)framework侧-startActivity的判断处理流程
- Activity的启动过程--startActivity()
- Android4.4 Framework分析——Launcher中启动应用程序(startActivity)的过程
- activity的启动模式,startactivity的过程
- startActivity 的启动过程源码分析学习
- App的启动过程(2)framework侧-恢复最上层的Activity
- StartActivity的流程
- startActivity()的流程
- Framework 的启动过程
- Framework的启动过程
- Framework的启动过程
- Android 5.0 startActivity的启动流程最全面的分析
- App的启动过程(3)应用进程侧-主线程的处理
- Activity的启动过程之startActivity源码解析
- App的启动过程
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- LTR学习排序 Learning to Rank 小结
- 整数排序
- ASP.NET Xml的读取
- 搭建JEESZ分布式架构7--Zookeeper注册中心安装
- axure原型设计之转盘抽奖
- App的启动过程(1)framework侧-startActivity的判断处理流程
- Zookeeper Listener分析
- MYSQL性能查看(命中率,慢查询)
- windows配置java环境变量的脚本
- chrome安装Postman插件
- UVa 11054 Wine trading in Gergovia——思路题
- Mysql函数整理
- Logistic逻辑回归总结
- 说说 JavaScript 的事件流