-
Notifications
You must be signed in to change notification settings - Fork 1
-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2019-08-13: 说说你对app(或进程)启动流程的理解? #11
Comments
App 启动流程
init zygote 当我上面没说,直接跳到 system_server
参考资源1. 深入理解 Android |
App的启动方式: 热启动:当启动应用的时候,后台已经存在该应用的进程了,(列:按back和home应用虽然会退出但是应用的进程仍然在后台运行,可以进入任务列表查看)这个是热启动,因为热启动不会创建进程。所以app不会创建Applocation,只会初始化MainActivity。一个应用从创建到销毁只会执行一次Applocation。 应用的启动步骤: (1) Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity (2) ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态 (3) Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行 (4) ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信 (5) ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了 应用启动流程涉及到的类和对象: (1) Launcher:Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity,实现了点击、长按等回调接口,来接收用户的输入。 (2) ActivityManagerServices:简称AMS,服务端对象,负责系统中所有Activity的生命周期。 (3) ActivityThread:App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作 (4) ApplicationThread:用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。 (5) ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。 (6) Instrumentation:每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。 (7) ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。 (8) ActivityRecord:ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。 (9) TaskRecord:AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。 App启动白屏或黑屏的原因:是因为已进入到Activity,但是未加载到布局文件,就先显示来windows窗口的背景。黑屏/白屏就是显示的windows背景(这个就是theme的设置) App启动白屏或黑屏解决方案: (1) 为Theme设置背景图(会给人一种快速加载的感觉) <stylename="Theme.AppStartLoad"parent="android:Theme"> <itemname="android:windowBackground">@drawable/ipod_bg <itemname="android:windowNoTitle">true </style>(2) 为Theme设置透明属性(会给人较慢加载出来感觉) <stylename="Theme.AppStartLoadTranslucent"parent="android:Theme"> <itemname="android:windowIsTranslucent">true <itemname="android:windowNoTitle">true </style>App的启动优化: (1) Application的创建过程中尽量少的进行耗时操作 (2) 如果用到SharePreference,尽量在异步线程中操作 (3) 减少布局的层次,并且生命周期回调的方法中尽量减少耗时的操作 |
APP启动在项目中碰到过黑白屏的问题 为什么我的 APP 启动会白屏或者黑屏 有时候我们会发现,我们在启动我们自己的 APP 的时候,总是有那么点时间是白屏(黑屏),经过了白屏(黑屏)后才会进入我们的 APP。那么这是为什么呢? 有很多的初始化放到了 Application 中去完成了,那么这个时候刚打开程序的时候就会有个耗时,就会出现白屏的效果。 所以这里程序加载有个顺序,当打开一个 Activity 的时候,并且这个 Activity 所属的 Application 还没有运行,系统会首先为这个 Activity 创建一个进程,创建进程的时候就会调用 Application 的 onCreate 方法。进程的创建和 onCreate 内部的初始化是需要时间的,如果这个时候过长,没有任何反应的话,那么对于用户来说是不不知道的,用户还以为自己没有点到呢,所以很显然是不可能在原页面等待加载的,那么这个时候就有了 StartingWindow(PerviewWindow)的出现,StartingWindow 出现在应用程序进程创建并且初始化完成之前,是个临时的窗口,对应的 WindowType是 TYPE_APPLICATION_STARTING 作用就是告诉用户,系统已经收到我们的操作了,正在对程序进行初始化,只要初始化完毕后就会移除这个窗口。 所以其实我们看到的白屏或者黑屏就是 StartingWindow,那么为什么是白色或者黑色呢?我们一般都会给我们的 Application 和 Activity 设置 Theme,系统就会根据我们所设置的 Theme 来决定 StartingWindow 的颜色。我们都知道 Window 布局的顶层是 DecorView,而 StaringWindow 显示的是一个空的 DecorView,只是这个 DecorView 会应用我们的这个 Activity 所指定的 Theme。我们默认的 Theme 是 @android:style/Theme.Light 的话,这个时候就会产生白屏了。黑屏就是应用了 @android:style/Theme.Black,好了到这里我们就彻底明白为什么会出现白屏或者黑屏了。 App启动白屏或黑屏解决方案: (1) 为Theme设置背景图(会给人一种快速加载的感觉) <stylename="Theme.AppStartLoad"parent="android:Theme"> <itemname="android:windowBackground">@drawable/ipod_bg <itemname="android:windowNoTitle">true </style> (2) 为Theme设置透明属性(会给人较慢加载出来感觉)<stylename="Theme.AppStartLoadTranslucent"parent="android:Theme"> <itemname="android:windowIsTranslucent">true <itemname="android:windowNoTitle">true </style> App的启动优化:(1) Application的创建过程中尽量少的进行耗时操作 (2) 如果用到SharePreference,尽量在异步线程中操作 (3) 减少布局的层次,并且生命周期回调的方法中尽量减少耗时的操作 |
app的启动流程分析:https://www.jianshu.com/p/28281b54d318 |
首先放上我参考的文章,感觉写的不错。Android - Activity 启动过程 这过程太复杂了,里边涉及了好多的点。只能大致的说一下,我再继续研究一下,有新的发现和想法再补充上来 |
|
App 启动过程一、整体了解1、ActivityManagerService 简称 AMS,服务端对象,负责管理 Activity 生命周期。 2、ActivityThread App 的入口,启动 App 后,会调用 ActivityThread.main(),开启 Looper、MessageQueue,与 ActivityManagerService 配合完成对 Activity 的管理。 3、ApplicationThread 实现 ActivityManagerService 与 ActivityThread 之间的交互,在 ActivityManagerService 需要管理 Application 中 Activity 的生命周期时,通过 ApplicationThread 代理对象和 ActivityThread 通信。 4、ApplicationThreadProxy ApplicationThread 在服务端的代理对象,负责和客户端的 ApplicationThread 进行通信。 5、Instrumentation 每个应用程序只有一个 Instrumentation 对象,每个 Activity 内都有一个对该对象的引用,可以理解为应用进程的管家,ActivityThread 需要创建或者暂停某个 Activity 时,都需要通过 Instrumentation 进行操作。 6、ActivityStack Activity 在 AMS 中的栈管理,用来记录已经启动的 Activity 的先后顺序、状态信息等,通过 ActivityStack 决定是否需要启动新的进程。 7、ActivityRecord ActivityStack 管理的对象,每个 Activity 在 AMS 对应一个 ActivityRecord,用来记录 Activity 的状态以及其他管理信息,其实就是服务器端 Activity 对象的映射。 8、TaskRecord AMS 抽象出来的一个任务的概念,是记录 ActivityRecord 的栈,一个 Task 包含若干个 ActivityRecord,AMS 通过 TaskRecord 确保 Activity 启动和退出的顺序。 二、Zygote在 Linux 中,所有的进程都是由 init 进程直接或间接 fork 出来的,Zygote 进程也不例外。 手机开机后,Linux 内核加载完成后,会启动一个 init 进程。 每一个 App 其实都是:
所以,在系统中的第一个 Zygote 进程启动之后,再打开一个 App,其实就是开启一个新的进程。而为了实现资源共用和更快的启动速度,Android 系统开启新进程的方式是:通过 fork 第一个 Zygote 进程开启新进程,换句话说,其他应用所在的进程都是 Zygote 的子进程。 三、SystemServerSystemServer 是一个进程,也是由 Zygote 进程 fork 出来的。 系统里比较重要的服务都是从这个进程里开启的,比如 ActivityManagerService、WindowManagerService、PackageManagerService 等。 Zygote 开启的时候会调用 ZygoteInit.main()
四、ActivityManagerService简称 AMS,服务端对象,负责系统中所有 Activity 生命周期。 初始化时机:SystemServer 进程开启时。
这是系统进程开启时的流程,在这之后,会开启系统的 Launcher 程序,完成系统界面的加载与显示。 五、Android 系统里面的服务器和客户端服务器端:所有 App 共用的系统服务,比如 ActivityManagerService、PackageManagerService、WindowManagerService 等,当某个 App 要进行某项操作时,要告诉这些系统服务。 客户端:某个 App。 App A 调用 startActivity 不能直接打开 App B 的某个页面,而是通过一系列调用,告诉 AMS 要打开 App B 的某个页面,AMS 会通知 Zygote 进程 fork 一个新进程,来开启 App B。 App 与 AMS 之间通过 Binder 进行 IPC 通信,AMS 与 Zygote 之间通过 Socket 进行通信。 AMS 的用途:
六、LauncherLauncher 本身也是一个应用程序。 七、Instrumentation 和 ActivityThread每个 Activity 都持有 Instrumentation 对象的一个引用,但整个进程只会存在一个 Instrumentation 对象。 当 startActivityForResult() 调用之后,实际上还是调用了 mInstrumentation.execStartActivity()。 这个类里面的方法大多数和 Application 和 Activity 有关,这个类就是完成对 Application 和 Activity 初始化和生命周期的工具类。 AMS -> ActivityThread -> Instrumentation 八、AMS 与 ActivityThread 之间的 Binder 通信
ActivityManager.getService() 返回的就是 ActivityManagerService 的远程接口。 客户端:ActivityManagerProxy -> Binder驱动 -> ActivityManagerService:服务器 如果 AMS 想要通知 ActivityThread 做一些事情,还是通过 Binder 通信,不过是换成了 ApplicationThread 和 ApplicationThreadProxy。 ApplicationThreadProxy:服务器 -> Binder 驱动 -> 客户端:ApplicationThread 九、问答1、一个 App 的程序入口到底是什么?ActivityThread.main()。 2、整个 App 的主线程的消息循环是在哪里创建的?是在 ActivityThread 初始化的时候,就已经创建消息循环了,所以在主线程里面创建 Handler 不需要指定 Looper,而如果在其他线程使用 Handler,则需要单独使用 Looper.prepare() 和 Looper.loop() 创建消息循环。 3、Application 是在什么时候创建的?onCreate()什么时候调用的?也是在 ActivityThread.main() 的时候,再具体点,就是在 thread.attach(false) 的时候。 参考:APP启动过程 |
No description provided.
The text was updated successfully, but these errors were encountered: