zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    show()的几种方法
    sql的交叉连接,内连接,左外连接,右外连接,全外连接总结
    MySQL数据库引擎介绍、区别、创建和性能测试的深入分析
    RedHat9通过Host-only配置网络连接
    解决Struts2.2.20版本的标签不支持style属性的问题
    SQL查询数据库中所有含有某一列的所有表
    简单工厂模式
    vc常用类总结(转载)
    嵌入式程序员应知道的0x10个C语言Tips
    C语言位操作
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7017163.html
Copyright © 2011-2022 走看看