您的位置:首页 > 移动开发 > Android开发

【Android源码学习】应用启动过程

2016-11-24 14:50 447 查看
1、手机启动完成后,显示的桌面Launcher其实也是一个应用(它继承于Activity)。手机上所安装的用户app都会显示在Launcher应用的界面上,类似于文件浏览器。

2、当我们点击某一个应用图标时,触发Launcher的onClick事件,它根据点击的内容(文件夹或应用图标)来实施相应的操作。因为点击的是应用图标(相于当快捷方式),所以执行的操作是启动这个应用。

3、启动应用时强制添加FLAG_ACTIVITY_NEW_TASK(入口Activity最多只有一个实例),然后调用Activity的startActivity方法,也就是调用startActivityForResult方法。

4、这里概念就比较多了,我们只要Activiy等的生命周期其实就是ActivityThread管理的,它不是线程但是它管理着进程的主线程,所以通常也叫它主线程。它有一个内部类ApplicationTread,它也不是线程,而是ActivityManagerService的Binder。ActivityThread就是通过ApplicationThread来和AMS进行通信的。

5、也就是Launcher通过Binder机制通知AMS要启动一个Activity(新应用的Activity,要创建新的进程)。AMS调用Activity记录栈ActivityStack.startActivityMayWait来做一些准备工作。

6、ActivityStack通过一系列函数调用,判断是否需要创建新的进程以及是否需要创建新的Activity。

7、因为是新启动一个应用,所以肯定要创建新的进程,同时要将新创建一个Activity并放到ActivityStack的栈顶(这时只是创建了ActivityRecord而不是Activity)。那么当前栈顶的Activity肯定要先进入pause状态。于是ActivityStack通过Binder机制通知当前应用Launcher的ActivityThread暂停当前activity。

8、而Binder(ApplicationThread)又是通过ActivityThread内部Hanlder类H来调用ActivityThread的handlerPauseActivity的,至于为什么要用Handler不懂,ApplicationThread不是和ActivityThread处于同一线程吗?

9、handlerPauseActivity暂停当前Activity后,又通过Binder机制通知AMS调用activityPaused,也就是ActivityStack调用activityPaused。

10、ActivityStack执行一系列方法后又继续调用AMS的startProcessLocked方法。该方法再次检查进程是否存在,因为不存在,它调用Process.start方法创建新的进程,并导入ActivityThread类,执行它的main入口方法。

11、ActivityThread的静态main方法会新建一个ActivityThread实例并调用它的attach方法,然后这个进程(也就是新应用的进程)就会进入消息循环直到进程退出。

12、ActivityThread的attach方法通过Binder机制调用AMS的attachApplication函数,经过一系列操作调用ActivityStack的realStartActivityLocked。这个函数最终通过Binder驱动程序进入到ApplicationThread的scheduleLaunchActivity函数中。

13、然后实际上是调用ActivityThread类的handleLaunchActivity函数。它首先调用performLaunchActivity函数来加载要创建的Activity类,然后调用handleResumeActivity函数来使这个Activity进入Resumed状态。

14、performLaunchActivity函数同时创建Application和Activity的上下文,并调用Activity的attach方法将这些信息设置到Activity中。然后通过mInstrumentation调用它的onCreate函数。

15、这样一个应用程序和Activity就启动了。

很多细节还是不太懂,Mark。

罗升阳:应用启动过程

继续加强一下概念理解:

1、ActivityThread和进程、线程、Activity的关系。

理解:从应用启动过程可以知道。ActivityManagerService通过Process.start方法创建一个新的进程,并将ActivityThread的类名作为第一参数传入。

查看Process.start源码可以看到它的方法注释
@param processClass Class name whose static main() to run
,也就是说第一个参数类中必须要有一个静态main方法,同时进程创建以后也会执行这个方法。

再看ActivityThread的静态main方法。

Looper.prepareMainLooper();

ActivityThread thread = new ActivityThread();
thread.attach(false);

if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();


可以看出,正是在静态main方法中调用了Looper.prepareMainLooper()方法,创建了一个ActivityThread实例,并将实例的Handler赋给静态变量sMainThreadHandler。

好像还是不太懂到底什么是线程。



2、为什么主线程不会因为Looper.loop里的死循环卡死?

这里有一个概念要弄清楚,卡
4000
死应该是指不能响应后续的操作或输入。Looper.loop确实是一个死循环,在没有消息时,主线程会阻塞而让出CPU,当有消息时再处理消息。通常一个消息能很快处理完,因此下一个消息到来的时候能很快地处理,看上去很流畅没有卡顿。相反,如果某个消息主线程需要很长时间去处理,这个时候在处理完这个消息之前主线程都无法响应其他消息,这时主线程就会出现卡顿。也就是说,主线程的卡顿不是因为loop循环,而是因为某个消息耗时。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android源码