1.点击app的启动图标时,Launcher进程通过Binder 向System_Server(AMS)发起startActivity请求,
2.System_Server进程(AMS)接受请求后,通过Socket方式向Zygote进程发送创建进程请求,然后Zygote进程通过Socket方式fork创建出一个新的APP进程分配给该应用;(只有和Zygote进程相关的用到了Socket通信)
为什么Zygote通信为什么用Socket,而不是Binder?
先后时序问题:
虽然Zygote更晚创建,但是不能保证通过Zygote进程去注册binder的时候,ServiceManager已经初始化好了(参考Binder C/S原理)。注册时间点无法保证,AMS无法获取到Zygote的binder引用,这是原因。
(附上开机到Launcher启动图)
3.APP进程通过Binder向System_Server(AMS)发起attachApplication请求,然后System_Server(AMS)再返回来给App进程发送scheduleLaunchActivity请求,告诉ActivityThread通过反射方式启动main方法,开启消息循环loop;以及告诉ActivityThread##H(Handler) 来反射启动创建Application 实例同时回调onCreate等方法,之后依次创建和初始化Application类,调用performLaunchActivity创建MainActivity类,加载主题样式Theme中背景等属性;然后再inflate布局,当oncreate/onstart/onresume方法都走完了之后,最后才对contentview进行measure/layout/draw显示再界面上,到此,应用的第一次启动才算完成;
4. 同时Laucher进程也会调用onPause暂停
总结上述app启动流程:
Application构造器方法--->Application中attachBaseContext()---> Application中的contentProvider初始化 ---> Application中onCreate()--->Activity构造方法--->onCreate()--->配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上。
在onCreate中设置layout布局 创建window,在onResume中关联window测量绘制布局并显示window;
oncreate创建window,onresume显示window;
Window创建流程:
onCreate: 在上面调用了handlerLanchActivity之后,在创建Activity的同时并在里面新建了一个PhoneWindow对象和DecorView对象同时获取到WindowManager,WindowManger负责和WMS进行Binder通信
onResume: 调用了Activity.makeVisible()后会创建一个ViewRootImpl,然后将Decorview传入并被ViewRootImpl管理,同时将Window和WMS关联起来,比如DecorView的添加移除等view逻辑事件操作都是ViewRootImpl管理;ViewRootImpl实现了ViewParent这个接口,接口中常见方法requestLayout(),其实是调用了ViewRootImpl;所以当View的ViewParent都是同一个时,可理解为这些View都在一个View链上,invalidate的时候会将整个viewtree遍历刷新一遍;
优化应用启动时间:
1.在Application类中的构造器/attachBaseContext/onCreate方法中不要进行耗时操作;
2.如果在Activity类中对sp进行初始化,由于sp的特性会把数据全部读出来并放在内存里,所以大文件的sp初始化可以放在异步线程中处理而不放在主线程中;
3.对于Activity类初始化,因为计算启动时间是到获取第一帧截至,所以尽量减少布局层次性,以及onCreate、onStart、onResume方法中避免做耗时操作;
热启动:
上述时冷启动应用的流程,热启动是针对按下back键、home键,仍保留了应用的后台的情况,所以会从已有的进程中来启动应用,所以热启动就不会重新fork进程、创建和初始化Application,而是直接进行MainActivity的初始化;
使用ActivityManager API时调用AMS服务的原理:
Android中Activity Manager相关类继承层次关系
看一下类结构图如下:
IActivityManager作为ActivityManagerProxy和ActivityManagerNative的公共接口,所以两个类具有部分相同的接口,可以实现合理的代理模式;ActivityManagerProxy代理类是ActivityManagerNative的内部类;ActivityManagerNative是个抽象类,真正发挥作用的是它的子类ActivityManagerService(系统Service组件)
这里涉及两个过程:
代理对象建立:ActivityManagerProxy代理对象的创建;
程序执行过程:如何通过代理对象来执行真正对象请求;
从图中可以看出代理类:使用ActivityManagerProxy代理类,来代理ActivityManagerNative类的子类ActivityManagerService;ActivityManagerService是系统统一的Service,运行在独立的进程中;通过系统ServiceManger获取;
ActivityManager运行在一个进程里面,ActivityManagerService运行在另一个进程内,
对象在不同的进程里面,其地址是相互独立的;实现跨进程的对象访问,需要对应进程间通信的规则,此处是采用Binder机制实现跨进程通信;所以此处的Proxy模式的运用属于:远程代理(RemoteProxy)。
代理实现过程
1 代理对象建立
是在ActivityManager的getRunningServices执行时就需要代理类来执行;
public List<RunningServiceInfo> getRunningServices(int maxNum)
return ActivityManagerNative.getDefault()
getServices(maxNum, 0);
}
继续看看ActivityManagerNative.getDefault()到底干了什么事:
实际上是关乎到Singleton<IActivityManager>类型的gDefault对象创建;
private static final Singleton<IActivityManager> gDefault = new
Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
ServiceManager.getService("activity");获取系统的“activity”的Service,
所有的Service都是注册到ServiceManager进行统一管理。
这样就创建了一个对ActivityManagerService实例的本地代理对象ActivityManagerProxy实例。Singleton是通用的单例模板类。
ActivityManagerNative.getDefault就返回一个此代理对象的公共接口IActivityManager类型,就可以在本地调用远程对象的操作方法。
2 执行过程
这个执行过程就设计到ActivityManager框架的执行流程;简单看一下这个getServices的执行过程。
此图表明整个Client对Service的访问是通过Service的代理对象Proxy进行访问的。
Android中对Service访问的模式都是以Client/Server模式进行;Client实际上访问Service是通过对Service的建立代理的Proxy对象进行访问的——代理模式。