当前位置:   article > 正文

Android Activity启动流程○

android activity启动流程

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。

02d9017cc8e74ac29d86ba6deddc23b3.webp

点击桌面图标,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来进行具体的操作。

478dc37de17045bd8b240b5688c54cec.jpg

Activity向AMS发出startActivity请求,这意味着Activity可以与AMS进行通信,但是AMS却不能与Activity通信,因为Binder是单向的。所以要实现在Activity发出请求之后AMS可以通知Activity发生状态改变,就要在AMS到Activity这个过程也建立一个Binder:

f2cfd05d878c4d74a3686551439da21c.jpg

SystemServer进程在收到请求后,通过IPC向应用进程发送scheduleLaunchActivity请求,应用进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息,主线程在收到Message后,创建目标Activity,并回调Activity.onCreate()等方法。

也就是说,AMS到Activity这个过程建立了一个Binder,Activity到AMS这个过程也建立了一个Binder,这样就能相互通信了。

c8ec60f4a69f4743be8382f548c960dd.jpg

这就是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。

4c263b5e980c47ba926b4fd2adfcc828.jpg

 整个过程涉及到的进程:

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中的方法与服务端进行通信了。

第一阶段的时序图:

bb3183065ea84c758b98077ec120af21.png

execActivity方法最终调用ATMS中的startActivity()方法发起启动Activity请求,获得启动结果result。然后调用checkStartActivityResult方法,传入result来判断能否启动

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/528848
推荐阅读
相关标签
  

闽ICP备14008679号