App 启动过程(含 Activity 启动过程) | 安卓 offer 收割基
Posted u012551350
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了App 启动过程(含 Activity 启动过程) | 安卓 offer 收割基相关的知识,希望对你有一定的参考价值。
本文作者: 布兰柯基
本文链接:
https://blankj.com/2018/12/18/android-adapt-screen-killer/
618,祝大家购物愉快,文末有彩蛋~~
这道题在曾经面试「菜鸟网络」中遇到过,不过当时只问了「Activity 启动过程」,这里对整个「App 启动过程」进行完整的源码分析,希望可以帮助到大家。
源码分析
1. Launcher 捕获点击事件,其过程为 Launcher#onClick
-> Launcher#onClickAppShortcut
-> Launcher#startAppShortcutOrInfoActivity
-> Launcher#startActivitySafely
-> Activity#startActivity
,其 Launcher3 相关源码如下所示:
2. 以 API 27 源码为例,说到了 Acitvity#startActivity
,我们点击源码可以发现调用的是 Activity#startActivityForResult
,其中调用到了 Instrumentation#execStartActivity
这个方法,源码如下所示:
3. 在 Instrumentation#execStartActivity
中我们可以发现它调用了 ActivityManager#getService()#startActivity
,其 ActivityManager#getService()
是采用单例,返回的是实现 IActivityManager
类型的 Binder
对象,它的具体实现是在 ActivityManagerService
中。
4. 我们再到 ActivityManagerService#startActivity
查看其源码,发现其调用了 ActivityManagerService#startActivityAsUser
,该方法又调用了 ActivityStarter#startActivityMayWait
,源码如下所示:
5. 我们查找到 ActivityStarter#startActivityMayWait
,其间调用了 ActivityStarter#startActivityLocked
,接着是 ActivityStarter#startActivity
,然后是 ActivityStarter#startActivityUnchecked
,其调用了 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
,源码如下所示:
6. 到 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
中查看发现其调用了 ActivityStack#resumeTopActivityUncheckedLocked
,然后是 ActivityStack#resumeTopActivityInnerLocked
,接着变又回到 ActivityStackSupervisor.java
,调用了 ActivityStackSupervisor#startSpecificActivityLocked
,这个方法中会判断要启动 App 的进程是否存在,存在则通知进程启动 Activity,否则就先将进程创建出来,其源码如下所示:
7. 我们分析进程尚未存在的情况,因为我们后续还会再次遇到 ActivityStackSupervisor#realStartActivityLocked
,ActivityStackSupervisor#startSpecificActivityLocked
中创建进程使用到的 mService
为 ActivityManagerService
,我们查看 ActivityManagerService#startProcessLocked
的源码如下所示:
8. 发现最终调用的事 Process#start
来启动进程,进程的入口就是在 android.app.ActivityThread.java
类中的 main()
函数,因此接下来我们从 ActivityThread#main
来分析,其调用了 ActivityThread#attach
,其中 ActivityManager.getService()
之前提到过,返回的是一个是实现 IActivityManager
类型的 Binder
对象,它的具体实现是在 ActivityManagerService
中,相关源码如下所示:
9. 我们又回到了 ActivityManagerService
中,查看其 attachApplication
函数,发现调用了 thread#bindApplication
和 mStackSupervisor#attachApplicationLocked
我们依次讲解这两个方法要做的事情,源码如下所示:
10. 上面说到的thread#bindApplication
中的这个 thread
是来自于 ActivityThread#mAppThread
,其类型是 ApplicationThread
,是 ActivityThread
的一个内部类,继承自 IApplicationThread.Stub
,我们来查看 ApplicationThread#bindApplication
,发现最后调用了 ActivityThread#sendMessage
方法,它内部调用了 mH.sendMessage
来发送消息,mH
是 ActivityThread
的内部类 H
的一个实例,查看 H#handleMessage
来查看它是怎么处理发送过来的消息,其最终走到了 ActivityThread#handleBindApplication
。
在源码中我们可以发现它先创建 mInstrumentation
对象,调用 data#info#makeApplication
来创建 Application
对象,其对象 data#info
为 LoadedApk
的一个实例,查看 LoadedApk#makeApplication
中代码可以发现,其调用了 Instrumentation#newApplication
方法,内部靠 Class#newInstance()
完成对 Application
实例化,然后调用 Application#attach(context)
来绑定 Context
。
以上创建完 Application
对象后便是调用 Instrumentation#callApplicationOnCreate
走 Application
的 onCreate
生命周期,以上涉及到的全部源码如下所示:
11. 说完了 9 中的 thread#bindApplication
,下面我们继续说 mStackSupervisor#attachApplicationLocked
,其 mStackSupervisor
是 ActivityStackSupervisor
的一个实例,我们查看 ActivityStackSupervisor#attachApplicationLocked
方法中发现会调用 ActivityStackSupervisor#realStartActivityLocked
,其方法会调用 app#thread#scheduleLaunchActivity
,源码如下所示:
12. 上面说到的 app#thread#scheduleLaunchActivity
中的 thread
是前面提到过的 IApplicationThread
,它的实现类是 ActivityThread#ApplicationThread
,我们查看 ActivityThread#ApplicationThread#scheduleLaunchActivity
中的代码发现最终是发送 LAUNCH_ACTIVITY
消息,这步我们在第 10 步中有过分析,我们直接查看其处理消息相关代码即可,在 H#handleMessage
中,我们可以看到其会接收并处理很多和四大组件相关的操作,我们查看对 LAUNCH_ACTIVITY
的处理,发现对其处理的方法是 ActivityThread#handleLaunchActivity
,它调用到了 ActivityThread#performLaunchActivity
方法,其中的实现再次涉及到了 Instrumentation
类,之前是在创建 Application
对象用到了它,如今是创建 Activity
对象又用到了它,其 Instrumentation#newActivity
也是通过 Class.newInstance()
来实例化 Activity
,实例化结束后回到 ActivityThread#performLaunchActivity
中来让 activity
依附到 window 中,然后callActivityOnCreate
走 Activity
的 onCreate
生命周期,涉及到的源码如下所示:
|
到此为止,一个 App 的启动过程已分析结束,最后献上启动涉及到的类的流程图:
结语
我正在打造一个帮助 Android 开发者们拿到更好 offer 的面试库————安卓 offer 收割基,欢迎 star,觉得不错的可以持续关注,有兴趣的可以一起加入进来和我一同打造。
https://github.com/Blankj/AndroidOfferKiller
推荐阅读
Android 自定义时钟控件 时针、分针、秒针的绘制这一篇就够了
微信扫一扫识别小程序
长按识别小程序,参与抽奖
以上是关于App 启动过程(含 Activity 启动过程) | 安卓 offer 收割基的主要内容,如果未能解决你的问题,请参考以下文章