Android系统启动流程

Android启动过程:系统引导Linux内核启动,内核启动时会加载Linux的各种设备驱动和数据结构,驱动加载完毕,Android系统才开始启动,启动过程中,系统加载第一个用户级别的进程:init,而launcher(桌面进程)是Android系统启动完毕之后,加载的第一个上层应用的进程。

Bootloader:引导程序 – DOS的启动盘
Linux Kernel:内核启动
Android:系统启动

init.c – 源码在system\core\init目录下

查看init.c代码,看main函数

init main(int argc,char **argv) {    ...    //执行Linux指令    mkdir("/dev",0755);    mkdir("/proc",0755);    mkdir("/sys",0755);    ...    //解析执行init.rc配置文件    init_parse_config_file("/init.rc");}

init.rc – 源码在system\core\rootdir – 包含非常多的可执行指令

播放开机动画:

service bootanim /system/bin/bootanimation    user graphics    group graphics    disabled    oneshot

启动孵化器进程:

service zygote /system/bin/**app_process** -Xzygote /system/bin -- zygote -- start-system-server    socket zygote stream 666    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart media    onrestart restart netd

app_process文件夹下的:源码在frameworks\base\cmds\app_process

app_main.cpp:启动了ZygoteInit服务!

int main(int argc, const char* const argv[]) {    ...    if (i < argc) {        arg = argv[i++];        if (0 == strcmp("--zygote", arg)) {            bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false;            setArgv0(argv0, "zygote");            set_process_name("zygote");            runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);    ...}

在ZygoteInit.java中

  • main()中:
public static void main(String argv[]) {    try {        ...        **preloadClasses();**        ...    } catch (RuntimeException ex) {    }}
  • preloadClasses():进行预加载类
private static void preloadClasses() {        ...        //解析PRELOADED_CLASSES文件,把该文件中定义好的1835个类全部预加载进来!        InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(PRELOADED_CLASSES);        //PRELOADED_CLASSES包含很多的java类!包括ActivityThread.java...        ...}
  • 回到ZygoteInit.java中的main()中:
public static void main(String argv[]) {    try {        ...        if (argv[1].equals("true")) {             **startSystemServer();** //启动系统服务!        } else if (!argv[1].equals("false")) {             throw new RuntimeException(argv[0] + USAGE_STRING);        }        ...    } catch (RuntimeException ex) {    }}
  • startSystemServer() – 启动系统服务
 /** * Prepare the arguments and fork for the system server process. */  private static boolean startSystemServer()          throws MethodAndArgsCaller, RuntimeException {      /* Hardcoded command line to start the system server */      String args[] = {          "--setuid=1000",          "--setgid=1000",          "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",          "--capabilities=130104352,130104352",          "--runtime-init",          "--nice-name=system_server",          **"com.android.server.SystemServer"**,      };      ZygoteConnection.Arguments parsedArgs = null;      int pid;      try {          parsedArgs = new ZygoteConnection.Arguments(args);          /* * Enable debugging of the system process if *either* the command line flags * indicate it should be debuggable or the ro.debuggable system property * is set to "1" */          int debugFlags = parsedArgs.debugFlags;          if ("1".equals(SystemProperties.get("ro.debuggable")))              debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;          /* Request to fork the system server process */          **pid = Zygote.forkSystemServer(                  parsedArgs.uid, parsedArgs.gid,                  parsedArgs.gids, debugFlags, null,                  parsedArgs.permittedCapabilities,                  parsedArgs.effectiveCapabilities);**      } catch (IllegalArgumentException ex) {          throw new RuntimeException(ex);      }    ...  }

SystemServer.java中的mian()方法中

public static void main(String[] args) {    ...    //加载动态链接库    **System.loadLibrary("android_servers");**    **init1(args);**    ...}

加载完成之后,在main()方法中又调用了init1(args);方法,显然发现init1()是一个本地方法,那么init1()方法有可能在动态链接库中;因此就找到了com_android_server_SystemServer.cpp:

com_android_server_SystemServer.cpp:源码存放在frameworks\base\services\jni目录下

namespace android {.../* * JNI registration. */static JNINativeMethod gMethods[] = {    /* name, signature, funcPtr */    { **"init1"**, "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },};...};

函数也是可以用指针的!因此我们可以知道init1的函数指针就是(void*) android_server_SystemServer_init1 ;这样的话也说明了init1由函数指针代替,因此init1执行的时候就会去执行android-server_SystemServer_init1()方法!那么在com_android_server_SystemServer.cpp中就不难发现有这样一个方法了!

namespace android {...static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz){    system_init();}...};

那么在android_server_SystemServer_init1()方法中会去调用system_init()方法:

namespace android {extern "C" int system_init();...};

该方法是一个抽象的方法,因此需要子类去覆写该方法!那么再去搜那里覆写了该方法;最后发现System_init.cpp类中覆写了这个方法:

System_init.cpp:

extern "C" status_t system_init(){   ......    //运行静态方法,要运行SystemServer类中的**init2()**方法    runtime->callStatic("com/android/server/SystemServer", "init2");   ......}

来到SystemServer类中的init2()方法:

public static final void init2() {    Slog.i(TAG, "Entered the Android system server!");    Thread thr = new ServerThread();    thr.setName("android.server.ServerThread");    thr.start();}

该方法创建了服务线程,并开启了线程,那么这样的话,就去看看线程到底干了些什么!去看看线程中的run()方法,在run()方法中,给ServiceManager添加了好多SystemService。这也是我们之所以能在java程序中使用getSystemService()方法能得到自己想要的Service,因为都在这里添加完成了。你尽管拿!ServerThread类就在本类当中,而run()因此也就在本类当中!

class ServerThread extends Thread {    ...    @Override    public void run() {        ...        ((ActivityManagerService)ActivityManagerNative.getDefault()).**systemReady**(new Runnable() {            public void run() {                ...            }        });        ...    }    ...}

在run()方法中,有一个重点:ActivityManagerService类中的systemReady()方法!

public void systemReady(final Runnable goingCallback) {    ...    //mMainStack:ActivityTask任务栈    **mMainStack.resumeTopActivityLocked(null);**}

ActivityTask.java中resumeTopActivityLocked方法中:

final boolean resumeTopActivityLocked(ActivityRecord prev) {    ...    // Launcher...    if (mMainStack) {        return mService.startHomeActivityLocked();    }    ...}

Handler消息机制

主线程有一个消息队列(MessageQueue),用来存储子线程中的handler.sendMessage()发送过来的消息,之后如果MessageQueue一旦有消息,那么就会去唤醒Looper.loop()轮询器,轮询器就会不断的检查MessageQueue有没有消息,如果有消息,那么就交给用户自己定义的Handler对象,去调用handler对象中的handleMessage()方法来处理消息。

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第1张图片

消息的创建:使用handler.obtionMessage(),但最终会调用Message类中的obtion()方法,来创建Message对象。

public final Message obtainMessage(){    return Message.obtain(this);}
public static Message obtain() {    synchronized (sPoolSync) {        if (sPool != null) {            Message m = sPool;            sPool = m.next;            m.next = null;            sPoolSize--;            return m;        }    }    return new Message();}

前提:
①、首先来看MessageQueue中的消息,按照队列的思想,先进先出去处理每一个消息
②、消息对象有一个成员属性:Message next。next本身也是一个消息。
android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第2张图片

a消息有一个成员属性next,而next也是一个消息,那么就是a指向b,b指向c–单链表的形式来维护消息的,而不是消息队列来维护的!因此消息是由消息自己来维护的,而不是靠消息队列来维护。

分析Message.obtain()方法中的代码:

if(sPool != null) {    Message m = sPool;    sPool = m.next;    m.next = null;    sPoolSize--;    return m;}

①. Message m = sPool;

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第3张图片

②. sPool = m.next;

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第4张图片

③. m.next = null;

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第5张图片

④. sPoolSize–;消息池中的消息被拿走了一条,所以总数减一。

⑤. return m;把a消息拿出去,a就离开了消息池,而sPool依然指向第一条消息。

handler创建:任何一个应用程序启动的时候,ActivityThread都会被创建。

ActivityThread中的main()方法中:

public static final void main(String[] args) {        ...        Looper.prepareMainLooper(); //创建轮询器        ...        ActivityThread thread = new ActivityThread();        ...        Looper.loop(); //开启轮询器,开始轮询,不断的检查消息队列是否有消息        ...    }}
  • 在Looper.prepareMainLooper()中:
public static final void prepareMainLooper() {    prepare();    ...}

在prepare()中:

public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); }    sThreadLocal.set(**new Looper()**); //创建轮询器,同时将会创建MessageQueue(消息队列)}
  • 在Looper.loop()中:
public static final void loop() {     ...     while (true) { //主线程       Message msg = queue.next(); // might block -- 如果消息队列没有消息,就会阻塞休眠       ...    }}

为什么阻塞休眠?

因为内存中的一块空间存放了特殊文件

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第6张图片

消息队列中有消息不会唤醒主线程的,唤醒主线程的是管道,就是当你往消息队列中发送消息的时候,会往管道中写数据,这样才会唤醒主线程。

消息发送: Message对象中有一个long类型记录自己的发送时间。

使用handler.sendMessage();通过handler对象调用各种方法来发送消息,不管你调用哪个方法,其实最终调用的都是sendMessageAtTime(),但前提是创建了Handler对象,一旦创建了对象必将调用其构造。

Handler对象构造方法:

public Handler(Looper looper) {    mLooper = looper;    mQueue = looper.mQueue; //从looper对象中拿到已创建好的MessageQueue对象    mCallback = null;}

sendMessageAtTime():

public boolean sendMessageAtTime(Message msg, long uptimeMillis){    boolean sent = false;    MessageQueue queue = mQueue; //从looper对象中拿到已创建好的MessageQueue对象    if (queue != null) {        msg.target = this; //绑定当前处理器(handler)        sent = **queue.enqueueMessage(msg, uptimeMillis);**//通过MessageQueue对象调用其enqueueMessage()方法    }    else {        ...    }    return sent;}

enqueueMessage():

final boolean enqueueMessage(Message msg, long when) {    if (msg.when != 0) {        throw new AndroidRuntimeException(msg + " This message is already in use.");    }    if (msg.target == null && !mQuitAllowed) {        throw new RuntimeException("Main thread not allowed to quit");    }    **final boolean needWake; //是否需要唤醒**    synchronized (this) {        ...        msg.when = when; //时间        Message p = mMessages; //消息队列里的第一条消息        if (p == null || when == 0 || when < p.when) {            msg.next = p;            mMessages = msg;            ...        }    }    if (needWake) {        nativeWake(mPtr); //唤醒主线程    }    return true;}

第一种情况:p == null;
android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第7张图片

第二种情况:when = 0;

msg.next = p;

mMessage = msg;

第三种情况:when < p.when;//说明你传进来的消息的事件小于消息队列中的第一条消息的时间。

如果三种情况都不满足,那么:

来了一条消息:准备往消息队列中去插

p = p.next;//此时此刻p指向b

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第8张图片

while(p.when < when);//p.when:表示b的时间,如果你传进来的消息的时间还比消息队列中的b消息的时间还大,那么就p又指向c消息,这样一次一次的进行对比:
一直这样,终于消息队列中的消息的时间,比你传进来的消息的时间大,那么就插入到c消息的前面。

如果此时,c消息的时间比你传过来的消息的时间大,那么就:
prev = p;
p = p.next;

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第9张图片

msg.next = prev.next;

prev.next = msg;

Looper轮询器:分发处理消息
①、Message对象中有一个Handler类型的成员变量target,这个target是记录此消息对象是由谁创建的。

②、多个Handler给同一个消息队列发送消息。
Looper.loop() – > next() – > dispatchMessage() – > handleMessage();

AsyncTask机制

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第10张图片

①、创建AsyncTask对象:

要执行execute()方法,首先就得创建AsyncTask对象,那么就会去执行其AsyncTask的构造方法,在其构造方法中:只是创建了WorkerRunnable对象,并没有去调用call(),因此不会去执行doInBackground()方法。

public AsyncTask() {    mWorker = new WorkerRunnable<Params, Result>() {//创建WorkerRunnable对象,是Callable的实现类。        public Result call() throws Exception {            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);            return doInBackground(mParams);//该方法目前还不会被执行,因为没有人调用call()方法。        }    };    //把WorkerRunnable对象传给了Future对象,作为其构造方法的参数。FutureTask是RunnableFuture的实现类,它的爷爷是Runnable。    mFuture = new FutureTask<Result>(mWorker) {       ......    };  ......}

②、在Future类的构造函数中:

③、创建了Sync对象,执行其构造方法:

private final Callable<V> callable;Sync(Callable<V> callable) {    this.callable = callable;//callable就是通过层层传递过来的WorkerRunnable对象。}

④、执行execute():

⑤、在execute()方法中的sExecutor.execute(mFuture)://sExecutor:是线程池。

private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(    CORE_POOL_SIZE,    MAXIMUM_POOL_SIZE,     KEEP_ALIVE,     TimeUnit.SECONDS,     sWorkQueue,     sThreadFactory);

那么用线程池的sExecutor.execute(mFuture)方法去执行一个Runnable对象,线程池会开启子线程去执行Runnable的run()方法。
FutureTask中的run()方法:

调用innerRun():

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第11张图片

使用Sync中的成员变量callable去调用了其自身的callable.call()方法,而callable就是一层一层传入过来的WorkerRunnable对象,这样调用call()方法就是调用WorkerRunnable中自身的实现好的call()方法,与此同时也就调用了call()方法中的doInBackground()方法,而doInBackground()方法是在子线程中被调用的。
那么,doInBackground()方法返回来的结果,赋值给了innerRun()中的result,而result有作为了set(result)参数传给了set()方法:

这里写图片描述

又调用了内部类Sync中的innerSet()方法:

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第12张图片

而方法中有调用了done()方法,而done方法我们可曾写过:
在AsyncTask构造函数中曾创建了FutureTask对象并覆写了done()方法:

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第13张图片

而sendToTarget()方法中又调用了sendMessage()方法:
同时target就是sHandler,那么将消息发送到消息队列当中,消息最终要被处理就会调用哪个发送消息的handler来处理,这里发送消息的就是sHandler,而sHandler又是哪里来的呢?
AsyncTask的内部类:

private static final InternalHandler sHandler = new InternalHandler();

android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)_第14张图片

MESSAGE_POST_RESULT:将会调用finish()方法:

这样就调用了onPostExecute(result);//result:就是doInBackground()所返回的结果。

All in all,because just begun!

更多相关文章

  1. TextView支持的XML属性及相关方法
  2. 详解Android应用中使用TabHost组件进行布局的基本方法
  3. Android 之 Looper、MessageQueue、Handler 与消息循环
  4. 简述Android消息机制及解惑
  5. Android的广播机制——Broadcast Reciver
  6. drawRoundRect方法:绘制圆角矩形
  7. Android不同版本获取当前wifi信息方法

随机推荐

  1. Android(安卓)NDK 异常 Error:No toolcha
  2. Android用代码测试Activity的生命周期
  3. Android通知栏点击无法启动Activity的问
  4. 最简便实现Android(安卓)ListView选中ite
  5. Android(安卓)Studio中使用开源库volley
  6. Android(安卓)设计模式之原型模式
  7. Android中实现长按照片弹出右键菜单
  8. Android(安卓)计算方法运行时间
  9. 在AndroidStudio中出现android no debugg
  10. Android-ListView中嵌套(ListView)控件时