Android启动原理剖析

我们知道Android是以一个Activity为单位的,但是我们并没有看到一个Activity是怎么开始启动的。今天我 们就从Android的源代码开始讲吧。

ActivityThread:

Android的一个apk在打开时,使用到的第一个类就是这个类。我们先来说这个类。等说完这个类就能了解Android应用程序的启动原理了。这货名字取名有一个Thread结尾,貌似是一个线程类。其实他并不是一个线程类,这个类没有继承任何类。或者说是直接继承在Object类。我们来看ActivityThread源码:

public final class ActivityThread {
    ....
}

这是ActivityThread定义时候的的源码,可以看出他根本没有继承任何类。那他为什么要以Thread来结尾的。貌似很不合理。其实不然。想必大家应该Android的异步线程机制吧。其实ActivityThread在创建的时候同时也启动了一个线程,这个线程就是一个异步线程,他创建出了MessageQueue,并同时进行消息的轮询,因此当这个应用程序在运行时,这个线程是一直都在的。这个线程就是应用程序的主线程,UI的处理等都是在这个线程处理的。

在AcitivityThread这个类的是有一个main方法的。我们知道java应用程序的入口就是main方法。这就是程序的入口。我们来看ActivityThread的源代码:

    public static void main(String[] args) {
        SamplingProfilerIntegration.start();
        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);
        Environment.initForCurrentUser();
        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());
        Security.addProvider(new AndroidKeyStoreProvider());
        Process.setArgV0("<pre-initialized>");
       //关键部分,看这里
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        AsyncTask.init();
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

其他的部分我们先不要管,先看关键部分,就是我注释的那个地方。在这里先是使用Looper.prepareMainLooper();方法来创建一个MessageQueue实例。prepareMainLooper内部会调用prepare()方法创建消息队列(MessageQueue)。创建出来之后,就会创建一个ActivityThread对象。这个ActivityThread对象内部会创建出一个Handler和一个ApplicationThread对象,其中这两个对象稍后会介绍,(这里应该有一个中断向量,或者然后再启一个线程去讲解Handler对象和Application对象,哈哈)先压一压。在创建出这个ActivityThread对象之后。中间部分略过不表。之后这里会调用Looper.loop(),是消息队里进行循环。所以说这个ActivityThread是一直都在的,因为需要一直等待取其他线程发过来的消息。这个线程就是我们的主线程。Activity,Service等的管理都是在这里。之后会介绍。

好了,这个过程想必大家都了解了,现在我们说一说我们的Handler和ApplicationThread。在ActivityThread中的这个Handler其实是一个内部类,类名是H,对,就是H一个字母,他是继承自Handler对象的。我们来看一下源代码:

在第3行,在这里我们可以看到,他创建了一个H类的实例。注意,这里是类的成员变量区域,不是在某个方法里面。意思就是这个类在创建的同时,这个mH对象就创建出来了。所以说这个mH相当于是主线程的,也就是在main里创建出来的。而这个对象是用于其他线程想主线程发消息的。我们再来看看main函数中我们没有提到的那部分:

      Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        AsyncTa

我们在if语句里面可以看到这样一个语句sMainThreadHandler = thread.getHandler();thread是刚刚创建出来的ActivityThread实例,而getHandler方法返回的正是mH实例。

接下来说一下ApplicationThread这个类,该类是ActivityThread的内部类,该类的作用是什么呢。其实这里涉及到了进程间的通信,这个类是负责接收远程的AmS(ActivitymanagerService)IPC(进程间通信)调用的。而这个的调用一般是Android系统去调用的,这个相当于一种进程间通信,Android系统会有一个服务,用于监控用户的操作等,当用户进行相关操作是会通过进程之间的通信去通知这个应用程序做相应的反应,比如启动一个Activity。当这个类收到通知之后,接下来就会安排Activity的启动,我们可以看一下这个类的源代码:

这里贴出其中的部分代码,注意不是这个类的全部代码,只是其中的一部分。我们看一下其中的第二个方法

schedulePauseActivity该方法的意思应该是“安排暂停activity”,该方法就是让Activity调用onPause的代码。下面的其他代码也都是类似的。都是管理service和activity的代码,在这些方法的内部都会调用sendMessage,而这个方法的内部又会继续调用mh.sendMessage()。将暂停或者启动Activity的相关消息安排到主线程的MessageQueue队列中,等待消息队列轮询来处理该消息。我们可以从这些方法的名字也能看出来,schedule是安排的意思,“安排暂停activity”就表示你把“暂停activity”这件事安排一下,等MessageQueue手头的事忙完,再来处理“暂停activity”的事。而安排这件事的人是谁呢,就是mH这个助理了,由他把消息发送给MessageQueue。

时间: 2024-10-09 08:25:36

Android启动原理剖析的相关文章

Android启动原理剖析【转】

我们知道Android是以一个Activity为单位的,但是我们并没有看到一个Activity是怎么开始启动的.今天我 们就从Android的源代码开始讲吧. ActivityThread: Android的一个apk在打开时,使用到的第一个类就是这个类.我们先来说这个类.等说完这个类就能了解Android应用程序的启动原理了.这货名字取名有一个Thread结尾,貌似是一个线程类.其实他并不是一个线程类,这个类没有继承任何类.或者说是直接继承在Object类.我们来看ActivityThread

MySQL 启动原理剖析

介绍 本篇文章主要从查看MySQL的启动命令的代码来详细了解MySQL的启动过程,内容多为概念知识:理解MySQL的启动原理对熟悉MySQL至关重要,启动mysql服务有三种方式分别是:mysql.sever,mysqld,mysqld_safe. my.cnf [client] socket=/tmp/mysql.sock port=3306 [mysqld] #################[base]########################## basedir =/usr/loc

spring boot 启动原理剖析

准备 SpringBoot为我们做的自动配置,确实方便快捷,若不大明白SpringBoot内部启动原理,以后难免会吃亏,所以这次博主就跟你们一起一步步揭开SpringBoot的神秘面纱,让它不再神秘. 旅程开始 开发任何一个SpringBoot项目,都会用到如下启动类: @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(A

Android BroadcastReceiver原理剖析

这里主要跟一下android源码,看看BroadcastReceiver的工作原理.BroadcastReceiver分动态注册和静态注册,静态注册涉及到系统开机时的程序安装过程,这里关于静态注册BroadcastReceiver的过程暂时不理,等写到程序安装会有相应的解说. 我们将从普通的Activity.registerReceiver开始: //android.app.ContextWrapper.java 464 @Override 465 public Intent registerR

Android启动篇 — init原理(一)

========================================================          ======================================================== =              [原创文章]:参考部分博客内容,学习之余进行了大量的筛减细化分析                          =          =                          [特殊申明]:避讳抄袭侵权之嫌疑

原理剖析-Netty之服务端启动工作原理分析(下)

一.大致介绍 1.由于篇幅过长难以发布,所以本章节接着上一节来的,上一章节为[原理剖析(第 010 篇)Netty之服务端启动工作原理分析(上)]: 2.那么本章节就继续分析Netty的服务端启动,分析Netty的源码版本为:netty-netty-4.1.22.Final: 二.三.四章节请看上一章节 四.源码分析Netty服务端启动 上一章节,我们主要分析了一下线程管理组对象是如何被实例化的,并且还了解到了每个线程管理组都有一个子线程数组来处理任务: 那么接下来我们就直接从4.6开始分析了:

Android自动化测试框架新书:&lt;&lt;MonnkeyRunner实现原理剖析&gt;&gt;交流

大家觉得编写一本描述MonkeyRunner原理分析的书籍如何?估计大概10万字左右.内容大概分布如下: Monkey实现原理: 去描述运行在目标安卓机器的monkey是如何运行并处理MonkeyRunner发送过来的事件请求并把事件注入到系统的 Monkey命令处理源码情景分析:去分析关键命令事件如touch,tap等的实现原理 AndroidDebugMonitor(adb)运行原理: 分析MonkeyRunner是如何使用ddmlib库的AndroidDebugMonitor来跟目标安卓设

EventBus的使用和原理剖析

尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38174537 代码下载:http://download.csdn.net/detail/yuanzeyao2008/7684041 在编程过程中,当我们想通知其他组件某些事情发生时,我们通常使用观察者模式,正式因为观察者模式非常常见,所以在jdk1.5中已经帮助我们实现了观察者模式,我们只需要简单的继承一些类就可以快速使用观察者模式,在Android中也有一个类似功能的开源库EventBu

android启动之zygote启动

上一博文介绍了init进程启动,在解析init.rc 的时候会把zygote加到service列表中,并最终启动,zygote启动的实际是app_process程序.zygote是init进程的子进程.在Android系统中,所有的应用程序以及系统服务,包括SystemServer都是由Zygote fork出来的,这就是为什么它叫zygote(受精卵)的原因.我们再来看一下.rc文件的描述: service zygote /system/bin/app_process -Xzygote /sy