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中
public static void main(String argv[]) {
try {
...
**preloadClasses();**
...
} catch (RuntimeException ex) {
}
}
private static void preloadClasses() {
...
//解析PRELOADED_CLASSES文件,把该文件中定义好的1835个类全部预加载进来!
InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(PRELOADED_CLASSES);
//PRELOADED_CLASSES包含很多的java类!包括ActivityThread.java...
...
}
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) {
}
}
/** * 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();
}
...
}
主线程有一个消息队列(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(); //开启轮询器,开始轮询,不断的检查消息队列是否有消息
...
}
}
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(消息队列)
}
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;
}
第二种情况: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对象:
要执行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!