Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-10-18:说说Activity加载的流程?

MoJieBlog opened this issue · comments

2019-10-18:说说Activity加载的流程?

一个APP启动的入口是ActivityThread的main, 而且这个Main方法是有系统进程启动的。
1、 在ActivityThread main方法中, 他会自己创建自己,并调用自己的attch方法,在这个方法里会获取一个叫IActivityManager的AMS代理,调用AMS的bindApplication方法,在AMS中,系统进程会创建一个app需要的一些比较的参数,如 pid uid等等,封装完成以后通过一个IApplicationThread的app进程的代理,调用bindApplication 绑定好Application创建的一些必要信息,然后通过handle发送消息并makeApplication创建出Application。
2、完成application创建,调用application的oncreate方法。在完成上面操作以后,AMS进程binapplication 完成以后,会继续通过一个叫ActivityStackSupervisor 继续调用启动Activity的方法,有个关键方法叫realStartActivityLock方法,它会创建ClientTransaction对象并且将LaunchActivityItem对象传递进去,最后还是通过IApplicationThread调用schedule方法。回到APP进程中,执行ClientTransaction的LaunchActivityItem的启动Activity方法,最后调用ActivityThread的handleLaunchActivity。他会通过反射创建出一个Activity对象并且,执行attch和onCreate、onStart 以及OnResume方法。
https://blog.csdn.net/dingshuhong_/article/details/102769669

App 启动流程(基于Android8.0):

  • 点击桌面 App 图标,Launcher 进程采用 Binder IPC(具体为ActivityManager.getService 获取 AMS 实例) 向 system_server 的 AMS 发起 startActivity 请求
  • system_server 进程收到请求后,向 Zygote 进程发送创建进程的请求;
  • Zygote 进程 fork 出新的子进程,即 App 进程
  • App 进程创建即初始化 ActivityThread,然后通过 Binder IPC 向 system_server 进程的 AMS 发起 attachApplication 请求
  • system_server 进程的 AMS 在收到 attachApplication 请求后,做一系列操作后,通知 ApplicationThread bindApplication,然后发送 H.BIND_APPLICATION 消息
  • 主线程收到 H.BIND_APPLICATION 消息,调用 handleBindApplication 处理后做一系列的初始化操作,初始化 Application 等
  • system_server 进程的 AMS 在 bindApplication 后,会调用 ActivityStackSupervisor.attachApplicationLocked,之后经过一系列操作,在 realStartActivityLocked 方法通过 Binder IPC 向 App 进程发送 scheduleLaunchActivity 请求;
  • App进程的 binder 线程(ApplicationThread)在收到请求后,通过 handler 向主线程发送 LAUNCH_ACTIVITY 消息;
  • 主线程收到 message 后经过 handleLaunchActivity,performLaunchActivity 方法,然后通过反射机制创建目标 Activity;
  • 通过 Activity attach 方法创建 window 并且和 Activity 关联,然后设置 WindowManager 用来管理 window,然后通知 Activity 已创建,即调用 onCreate
  • 然后调用 handleResumeActivity,Activity 可见

附图:

补充:

  • ActivityManagerService 是一个注册到 SystemServer 进程并实现了 IActivityManager 的 Binder,可以通过 ActivityManager 的 getService 方法获取 AMS 的代理对象,进而调用 AMS 方法
  • ApplicationThread 是 ActivityThread 的内部类,是一个实现了 IApplicationThread 的 Binder。AMS通过 Binder IPC 经 ApplicationThread 对应用进行控制
  • 普通的 Activity 启动和本流程差不多,至少不需要再创建 App 进程了
  • Activity A 启动 Activity B,A 先 pause 然后 B 才能 resume,因此在 onPause 中不能做耗时操作,不然会影响下一个 Activity 的启动

其实简单概括来讲,就是 startActivity - Instrumetaton Binder 与 AMS 通信,AMS 检验各种信息,如果没问题,ApplicationThread 发送信息给 ActivityThread ,ActivityThread 的Handler 启动 activity。详细看大图:
在这里插入图片描述

1 无论是通过Launcher启动Activity还是通过Activity内部调用StartActivity方法启动Activity最后都是通过Binder通信进入AMS中,并调用AMS的startActivity方法;
2 AMS经过一系列的方法调用进行一些启动的准备工作,比如解析Intent并保存在ActivityInfo中,根据启动模式进行相关任务栈的操作,创建新进程等等;
3 在待启动的Activity中,ActivityThread.main()方法会执行,然后再通过Binder进入AMS的attach方法,并传递ApplicationThread,AMS通过 ApplicationThread 对应用进行控制。
4 AMS会给目标进程创建processRecord,并初始化运行环境,最后通过realstartActivityLocked方法进入目标进程;
5 目标进程的ActivityThread.handleLanchActivity()执行加载Activity实例,加载成功后开始调用一系列生命周期方法。

**面试官,才会问这种问题,毫无意义,面试造凹凸曼,上班扭螺丝

**面试官,才会问这种问题,毫无意义,面试造凹凸曼,上班扭螺丝

大厂好多问的,没办法

commented

记录下比较好的文章 https://www.bbsmax.com/A/KE5QrOAydL/