赞
踩
1.Activity的启动
Android系统启动的过程:打开Android手机电源键后,先运行BootLoader,由BootLoader加载Linux内核,之后会启动init进程,init进程会启动Zygote进程,Zygote进程会调用system_server进程,system_server进程会拉起PMS和AMS。AMS会启动Launcher应用,Launcher应用就是Android的桌面应用,用来显示各个应用图标。当用户点击某一个app图标时就会fork一个新的进程,然后启动Activity。
而启动一个Activity,通常有两种情况,一种是在应用内部通过startActivity启动,另一种是通过Launcher启动。
Activity的启动要经过多次IPC,涉及Activity(或Launcher)、AMS、Zygote、新启动的app这4个进程,通过这四个进程的多次IPC通信最终启动一个App,然后启动它的Activity。
点击桌面图标,Launcher会启动程序默认的Activity,这个过程是在Launcher进程中进行的。然后通过binder进入ATMS,在ATMS中为应用的第一个activity创建ActivityRecord,找到其ActivityStack,将ActivityRecord插入到所在的TaskRecord的合适位置。然后通过ActivityManagerInternal::startProcess进入AMS,请求创建应用进程,这个过程会创建ProcessRecord对象并处理保存进程所需的各种信息,最后通过Process.start()请求创建应用进程。AMS并不直接创建应用进程,而是交给Zygote来创建,Zygote进程通过fork自身进程来创建新的应用进程,这样可以让新的应用进程继承自己的相关权限。最后AMS将启动Activity的信息转发给ApplicationThread,这又是一个跨进程的操作,从SystemServer进程到应用进程。ApplicationThread收到消息后,再通过H类(Handler,指向UI线程)将消息发送到UI线程,再在UI线程启动应用,接着调用onCreated方法,实现应用的启动。
其中涉及几个概念:
①ActivityManagerService:AMS是Android中最核心的服务,继承自IActivityManager.Stub,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作。AMS处于SystemServer进程中,因此app进程使用AMS时会通过Binder机制与SystemServer进程进行通信。
②ActivityManagerNative:由于AMS是系统核心服务,在SystemServer进程里面,它的很多API不能直接开放供客户端使用,所以需要通过IPC的方式。具体是:ActivityManager类内部调用AMN的getDefault函数得到一个ActivityManagerProxy对象,通过它与AMS通信。
③ActivityManagerProxy:AMP是AMS在客户端的代理,客户端通过AMP间接调用AMS。
④ActivityThread:应用程序的主线程,也是应用程序的入口;消息循环机制的创建、初始化信息等都在ActivityThread中完成。
⑤ApplicationThread:用来实现AMS与ActivityThread之间的交互。在AMS需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
⑥ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。
⑦Instrumentation:每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,监控着应用进程和系统的所有交互。ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
Activity向AMS发出startActivity请求,这意味着Activity可以与AMS进行通信,但是AMS却不能与Activity通信,因为Binder是单向的。所以要实现在Activity发出请求之后AMS可以通知Activity发生状态改变,就要在AMS到Activity这个过程也建立一个Binder:
SystemServer进程在收到请求后,通过IPC向应用进程发送scheduleLaunchActivity请求,应用进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息,主线程在收到Message后,创建目标Activity,并回调Activity.onCreate()等方法。
也就是说,AMS到Activity这个过程建立了一个Binder,Activity到AMS这个过程也建立了一个Binder,这样就能相互通信了。
这就是Activity与AMS之间的双向Binder连接, Activity用IActivityManager提供的API向AMS提出执行某个动作的请求(启动RemoteService);AMS通过IApplicationThread提供的API来控制Activity所在的应用程序,这些API包括schedulePauseActivity()、scheduleStopActivity()等。
Activity的启动流程大致分为三个过程:
①调用进程的Activity收集好信息后,向system_server进程的ATMS服务发起请求。
②ATMS向PKMS寻找启动的Activity信息和进程信息,如果启动的Activity进程没有被创建,则创建新进程,之后管理Activity的堆栈,并回调启动Activity所在进程的ApplicationThread类。
③ApplicationThread通过调用ActivityThread来反射调用启动Activity。
整个过程涉及到的进程:
Launcher进程->SystemServer进程->Zygote进程->SystemServer进程->应用进程。
3.第一阶段:Activity —> ATMS
Launcher本身是一个Activity,在用户点击应用图标时调用startActivitySafely方法,最后调用到Activity.startActivity():
Launcher.java:
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
...
intent.addFlags(Intent.FLAG_ACTIVITY_NE W_TASK);//标记在新的栈启动
startActivity(intent, optsBundle);
}
然后调用Activity.startActivity()(到这里,就与通过startActivity方法跳转到另一个activity的流程是一样的了)。
Activity.java:
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, Bundle options) {
...
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
在startActivity里调用startActivityForResult方法:
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent,requestCode,null);
}
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
...
//通过Instrumentation的execStartActivity方法来启动activity
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken,this,intent, requestCode, options);
}
注意调用execStartActivity方法时传入了一个参数mMainThread.getApplicationThread(),它的类型是ApplicationThread,ApplicationThread是ActivityThread的内部类,继承自IApplicationThread.Stub,是一个Binder对象,具有跨进程通信的能力。ApplicationThread就是通过AIDL创建了一个远程服务的接口,用来与服务端进行交互,该对象会被传入到ATMS中,在ATMS中保存它的client(客户端),这样ATMS就可以与app进行通信了。
看下execStartActivity方法:
Instrumentation.java:
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread; //app端AIDL实现类
...
//通过Binder调用ATMS启动Activity。注意参数whoThread被传递过去,用于Activity和ATMS的通信(在ATMS中传递消息到ActivityThread)
int result = ActivityTaskManager.getService() .startActivity(whoThread,who.getBasePackageName(),who.getAttributionTag(),intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token,target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
}
调用ActivityTaskManager的getservice()会通过Binder得到一个ATMS的代理对象,之后ATMS开始startActivity。 ATMS是用于管理Activity及其容器(任务、堆栈、显示等)的系统服务,运行在系统服务进程system_server之中。
看一个ActivityTaskManager的getservice()方法:
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
//获取单例
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton = new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService( Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
IActivityManagerSingleton的get方法会调用create方法,先得到IBinder类型的ATMS引用,接着将它转化成IActivityTaskManager类型的对象,即ATMS的代理对象,这段代码采用的是AIDL,IActivityTaskManager.java类是由AIDL工具在编译时自动生成的。ATMS继承IActivityTaskManager.Stub类并实现相关方法。app通过这个代理对象和ATMS(ATMS所在的进程为SystemServer系统服务进程)进行跨进程通信。
ATMS是一个系统服务进程,在这里通过getService获取到它的Binder对象,然后将Binder转成AIDL接口所属的类型,接着就可以调用AIDL中的方法与服务端进行通信了。
第一阶段的时序图:
execActivity方法最终调用ATMS中的startActivity()方法发起启动Activity请求,获得启动结果result。然后调用checkStartActivityResult方法,传入result来判断能否启动
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。