10_Activity启动流程源码原理

Activity启动流程的了解:AMS和ActivityThread涉及到的源码?

我们以启动微信为例,看看启动流程是怎样的。

简单概括启动微信的流程就是:

1.Launcher通知AMS 要启动微信了,并且告诉AMS要启动的是哪个页面也就是首页是哪个页面

2.AMS收到消息告诉Launcher知道了,并且把要启动的页面记下来

3.Launcher进入Paused状态,告诉AMS,你去找微信吧

上述就是Launcher和AMS的交互过程

4.AMS检查微信是否已经启动了也就是是否在后台运行,如果是在后台运行就直接启动,如果不是,AMS会在新的进程中创建一个ActivityThread对象,并启动其中的main函数。

5.微信启动后告诉AMS,启动好了

6.AMS通过之前的记录找出微信的首页,告诉微信应该启动哪个页面

7.微信按照AMS通知的页面去启动就启动成功了。

上述阶段是微信和AMS的交互过程。

 

那么接下来我们分析下具体过程

Activity的startActivity方法开始分析,startAcitivity方法有好几种重载,但他们最终都会调用startAcitivityForResult方法。

startActivityForResult方法接着调用

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this,mMainThread.getApplicationThread()
,mToken,this,intent,requestCode,options);

其中mMainThread.getApplicationThread()这个参数,它的类型是ApplicationThread,ApplicationThread是ActivityThread的一个内部类(通过后面的分析可以发现,ApplicationThread和ActivityThread在Activity的启动过程中发挥着很重要的作用)

接着看Instrumentation的execStartActivity方法,有以下两个步骤:

1.

int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), 
	intent,intent.resolveTypeIfNeeded(who.getContentResolver()),t	oken, target != null ? target.mEmbeddedID : null,requestCode, 0, 	null, options);

启动Activity真正的实现由ActivityManagerNative.getDefault()的startActivity方法来实现。最终调用ActivityManagerService的startActivity方法。

ActivityManagerService(简称AMS)继承自ActivityManagerNative,而ActivityManagerNative继承自Binder并实现了IActivityManager这个Binder接口,因此AMS也是一个Binder,他是IActivityManager的具体实现。

由于ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象,因此它的具体实现是AMS。

在ActivityManagerNative中,AMS这个Binder对象采用单例模式对外提供,Singleton是一个单例的封装类,第一个调用它的get方法时它会通过create方法来初始化AMS这个Binder对象,在后续的调用中则直接返回之前创建的对象。

2.

checkStartActivityResult(result, intent);

就是检查启动Activity的结果。(当无法正确的启动一个Activity时,这个方法会抛出异常信息,比如当待启动的Activity没有在AndroidManifest中注册是,就会抛出异常)

接着进入到AMS中:

调用AMS的startActivity()方法,其方法内部会调用startActivityAsUser()方法,startActivityAsUser()方法内部会调用mStackSupervisor.startActivityMayWait()。

Activity的启动过程又转移到了ActivityStackSupervisor的startActivityMayWait方法中,

 

在ActivityStackSupervisor中:

在startActivityMayWait中又调用了startActivityLocked方法,

然后startActivityLocked方法有调用了startActivityUncheckedLocked方法,

接着startActivityUncheckedLocked又调用了ActivityStack的resumeTopActivitiesLocked方法,

这个时候启动过程已经从ActivityStackSupervisor转移到ActivityStack。

 

在ActivityStack中:

在resumeTopActivitiesLocked方法又调用了resumeTopActivityInnerLocked方法

然后resumeTopActivityInnerLocked方法又调用了ActivityStackSupervisor的startSpecificActivityLocked方法

(在ActivityStackSupervisor中)startSpecificActivityLocked方法调用了realStartActivityLocked方法

 

Activity启动过程在ActivityStackSupervisor和ActivityStack之间的传递顺序:

在ActivityStackSupervisor的realStartActivityLocked方法中一句主要的方法:

 app.thread.scheduleLaunchActivity()

app.thread的类型IApplicationThread它继承了IInterface接口,所以它是一个Binder类型的接口。

从IApplicationThread声明的接口方法可以看出,其内部包含了大量启动、停止Activity的接口,此外还包含了启动和停止服务的接口。

IApplicationThread这个Binder接口的实现者完成了大量和Activity以及Service启动/停止相关的功能。

IApplicationThread实现者是ApplicationThread。Application继承了ApplicationThreadNative,而ApplicationThreadNative则继承了Binder并实现了IApplicationThread接口(ApplicationThreadNative的作用其实和系统为AIDL文件生成的类是一样的)

在ApplicationThreadNative的内部,还有一个ApplicationThreadProxy类。

ApplicationThreadNative就是IApplicationThread的实现者,由于ApplicationThreadNative被系统定义为抽象类,所以ApplicationThread就成了IApplicationThread最终的实现者

Activity启动流程最终回到了ApplicationThread中,ApplicationThread通过scheduleLaunchActivity方法来启动Activity。

在ApplicationThread中,scheduleLaunchActivity的实现很简单,就是发送一个启动Activity的消息交由Handler处理(这个Hnadler的名字是H)

sendMessage(H.LAUNCH_ACTIVITY,r);

 

Handler H对“LAUNCHE_ACTIVITY”这个消息的会调用ActivityThread的handleLaunchActivity。而handleLauncheActivity方法中最终由performLaunchActivity方法来完成了Activity对象的创建和启动过程,并且handleLauncheActivity方法中还会调用handleResumeActivity方法来调用启动Activity的onResume这一生命周期方法。

 

performLaunchActivity主要完成几件事:

  1. 从ActivityClientRecord中获取待启动的Activity的组件信息
  2. 通过Instrumentation的newActivity方法使用类加载器创建Activity对象
  3. 通过LoadedApk的makeApplication方法来尝试创建Application对象(从makeApplication中可以看出,如果Application已经被创建过了,那么就不会再重复创建,这也就意味着只有一个Application对象。

Application对象的创建也是通过Instrumentation来完成的,这个过程和Activity对象的创建一样,都是通过类加载器来实现的。

Application创建完毕后,系统会通过Instrumentation的callApplicationOnCreate来调用Application的onCreate方法。

      4.创建ContextImpl对象并通过Activity的attach方法来完成一些重要数据的初始化

ContextImpl是Context的具体实现,Context中大部分逻辑都是ContextImpl来完成的。ContextImpl是通过Activity的attach方法来和Activity建立关联的

 

       5.调用Activity的onCreate方法

mInstrumentaion.callActivityOnCreate(activity,r.state),由于Activity的onCreate已经被调用,者也意味着Activity已经完成了整个启动过程

 

 

 

 

 

 

1.把要打开的Activity信息传递给AMS

Activity的startActivity

 

 

最终调用startActivityForResult()

 

 

                                                                                           

Instrumentation的execStartActivity()方法

其中有参数mMainThread.getApplicationThread()(类型是ApplicationThread,是ActivityThread的一个内部类)

 

 

ActivityManagerNative.getDefault()中startActivity方法

=ActivityManagerService的startActivity方法

 

checkStartActivityResult()检查启动Activity的结果

                                                     进入AMS

 

 

 

 

 

 

 

 

 

 

 

 

2.可能是检测线程是否启动有关的

startActivity()方法

 

 

                      startActivityAsUser()方法

 

 

ActivityStackSupervisor的startActivityMayWait()方法

 

 

                                          经过层层调用

(从ActivityStackSupervisor转移到ActivityStack)

 

 

 

ActivityStCK的resumeToActivitiesLocked()方法

 

 

 

ActivityStackSupervisor的startSpecificActivityLocked方法

ActivityStackSupervisor的realStartActivityLocked方法

 

 

 

 

 

app.thread.scheduleLaunchActivity()

App.threadl类型IApplicationThread,实现者是ApplicationThread

 

也就是相当于

ApplicationThread的scheduleLaunchActivity方法

 

 

  1. 正式打开页面:
  1. 找到要打开的XX页面Activity
  2. 加载Activity对象,做准备
  3. 创建Applicaiton对象
  4. 完成Activity的一些初始化操作
  5. 启动Acitivity

 

发送一个启动Activity的消息,交由Handler处理

 

 

 

H

 

 

LAUNCH_ACITVITY

 

 

ActivityThread的handleLaunchActivity

 

 

 

 

 

performLaunchActivity()方法

(1)从ActivityClientRecord中获取待启动的Activity组件信息

(2)通过Instrumentation的newActivity方法使用类加载器创建Activity对象

(3)通过LoadedApk的makeApplication方法尝试创建Application对象

(4)创建ContextImpl对象并通过Activity的attach方法来完成一些重要数据的初始化

   (5)调用Activity的onCreate()方法

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sun cat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值