【复习】Activity的启动(AMS实现交互)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_29266921/article/details/93654224

以下流程参考8.0源码

一、概述

无论Launcher启动Activity还是应用内启动Activity,都会调用startActivity殊途同归。

Launcher:一个应用程序,可以认为是桌面。Launcher启动Activity就是指,我们在桌面上点击了一个应用。应用内启动Activity就是跳转。

 

二、分析几个问题

①启动Activity后,生命周期是什么?

应用内启动,A跳转B,A-->onPause,B-->onCreate。(如果默认启动模式,不会开辟新栈)

Launcher启动A,Launcher-->onPause,A-->onCreate(开辟新栈)

②以上两种方式,都是跨进程通信吗?

是的,通过ActivityManagerService调度,Binder机制实现的跳转(这里挺复杂,后面会说到)。

③跨进程方式是什么?

Binder机制。

 

  • 流程概述

Step1:Launcher.startActivitySafely

从Launcher开始,Launcher.java继承了Activity,点击事件中调用Activity的startActivity。

 

Step2:Activity.startActivity

进入,继续调用startActivityForResult,这里面继续调用了Instrumentation.execStartActivity(...)。

 

Step3:Instrumentation.execStartActivity(...)

方法参数mmainThread.getApplicationThread:当前应用的ApplicationThread实例,此时是Launcher的。ApplicationThread继承了IApplicationThread.Stub,得知这是一个Binder对象,进而得知,它将用于IPC通信,即中介,谁和谁的中介呢?ActivityManagerService(后面简称AMS)和ActivityThread(此时代表Launcher的进程)。

为什么说他俩交互了?

进入Instrumentation.execStartActivity(...),发现ActivityManager.getService().startActivity(...),方法参数给了这个方法,绿色部分就是AMS,此时,已经进入了framework层了。

 

Step4:ActivityStarter.startActivityMayWait

继续深入,代码量很大,挑到主要的,将要跳转的Activity,即MainActivity,的信息封装成ActivityInfo。

另一方面,还调用了startActivityLocked(...),里面有ApplicationThread参数caller,代表的Launcher进程,将Launcher的信息保存到ActivityRecord中,一层层进去后,找到一个比较关键的代码,ProcessRecord callerApp = mService.getRecordForAppLocked(caller):有关当前正在运行的特定进程的完成信息,即Launcher进程信息,又给包装了一次,后边系统通知Launcher停止时,会用到它。

注:上面的ActivityRecord很重要,后面的方法都会携带,里面有用户交互的信息,也就是Binder对象,即ApplicationThread。

最终调用,startActivityUnchecked(...r),注:r:ActivityRecord,里面存储了callerApp。这里代码比较重要,总之就是创建了一个新栈,准备开启新的Activity,启动之前,要通知Launcher停止,自然就用到了AMS和ActivityThread的交互,正好回答了step3的问题。

准备就绪后,调用mSupervisor.resumeFocusedStackTopActivityLocked

 

Step5:ActivityStackSupervisor.resumeFocusedTopActivityLocked

Step4的两方面保存工作都准备就绪了,开始调用这个方法,进入后调用resumeTopActiivtyUncheckedLocked,继续调用targetStack.resumeTopActivityUncheckedLocked(target...),注:target:ActivityRecord(记录着Launcher信息,注意里面的caller,也就是ApplicationThread对象,即Binder对象)

 

Step6:ActivityStack.resumeTopActivityUncheckedLocked

根据注释找到resumeTopActivityInnerLocked,这里逻辑太多了,记不过来,直接找到关于Pause的和start的。

startPausingLocked停止

startSpecificActivityLocked 开启新的Activity

 

下面是停止操作

Step7:(在ActivityStack里)ActivityRecord.app.thread.schedulePauseActivity(...)

app:ProcessRecord(Launcher进程的完整信息,step4提到了)

Thread:ApplicationThread(Instrumentation方法参数,这是ActviityThread内部类)

注:方法参数prev.appToken,pre:ActivityRecord;appToken:窗口管理令牌(我们可以知道这是谁的窗口,可以理解成一个指针,或者一个地址,可以很快的找到相应的Activity)

方法里面发送了消息sendMessege,H.PAUSE_ACTIVITY,H:ActivityThread内部类,显然要停止launcher了,接收到消息之后handlePauseActivity((IBinder) args.arg1...)

(IBinder) args.arg1:上面的token,指向了Launcher的Activity

 

Step8:ActivityThread.handlePauseActivity

主要做了两件事:停止Launcher;通知AMS已经停止了。

停止Launcher:

performPauseActivity(token...),方法中,ActivityThread.get(token)得到一个ActivityClientRecord:客户端Activity的代表(在此,就是Launcher进程的Activity代表)。、

继续深入,发现performPauseActivityIfNeeded,这个方法里面,看到这一行代码

mInstrumentation.callActivityOnPause(r.activity),r:就上上面那个Activity代表。看到这 里终于明白了,终于从系统层跳出来了。

回忆一下,我们是从Instrumentation.execStartActivity进入到系统层(AMS)的,现在终于又从系统层回来了。

Instrumentation.callActivityOnPause里面执行activity.performPause,继续深入,终于开始调用activity.onPause了。

通知AMS,Launcher已经停止:

ActivityManager.getService().activityPaused(token)

 

下面是开启操作

开启操作不继续看了,头大,大体逻辑就是:zygoteProcess fork一个新进程,再次Binder交互,最终回调onCreate等生命周期,启动Activity

 

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页