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

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里的死循环卡死?
这里有一个概念要弄清楚,卡死应该是指不能响应后续的操作或输入。Looper.loop确实是一个死循环,在没有消息时,主线程会阻塞而让出CPU,当有消息时再处理消息。通常一个消息能很快处理完,因此下一个消息到来的时候能很快地处理,看上去很流畅没有卡顿。相反,如果某个消息主线程需要很长时间去处理,这个时候在处理完这个消息之前主线程都无法响应其他消息,这时主线程就会出现卡顿。也就是说,主线程的卡顿不是因为loop循环,而是因为某个消息耗时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值