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()方法来处理消息。

消息的创建:使用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本身也是一个消息。

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;

②. sPool = m.next;

③. m.next = null;

④. 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 -- 如果消息队列没有消息,就会阻塞休眠       ...    }}

为什么阻塞休眠?

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

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

消息发送: 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;

第二种情况:when = 0;

msg.next = p;

mMessage = msg;

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

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

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

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

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

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

msg.next = prev.next;

prev.next = msg;

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

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

AsyncTask机制

①、创建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():

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

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

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

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

private static final InternalHandler sHandler = new InternalHandler();

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

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

All in all,because just begun!

更多相关文章

  1. Android线程优先级设置方法
  2. 简述Android消息机制及解惑
  3. Android(安卓)之 Looper、MessageQueue、Handler 与消息循环
  4. TextView支持的XML属性及相关方法
  5. Android(安卓)中 OnTouch事件的研究
  6. Android(安卓)UI的绘制流程
  7. Android字体大小多屏幕适配
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android权限安全(5)组件的android:export
  2. 深入浅出Android消息系统之一
  3. [转]Jollen 的 Android 教學,#4: 使用 XM
  4. android-gradle-plugin3.0.1源码分析
  5. android中SharedPreferences用法详解
  6. Android跨进程bindService与callback
  7. Android 中 Service 学习,总结
  8. Android APK开发 Drawable文件夹下的自定
  9. 全面认识Android中Gradle相关配置文件
  10. Android 的 Activity 组件详解