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

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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值