当前位置: 代码迷 >> Android >> Android系统启动->应用启动->界面的显示(一)
  详细解决方案

Android系统启动->应用启动->界面的显示(一)

热度:63   发布时间:2016-04-28 03:10:55.0
Android系统启动-->应用启动-->界面的展示(一)

参考资料:
1,老罗的Android之旅http://blog.csdn.net/luoshengyang/article/details/6689748
2,Android核心分析http://www.linuxidc.com/Linux/2011-04/33966.htm

Android系统的启动:
我们想来一张系统架构图:
               

一,上面用Git下载编译过程略掉,直接看最后我们Build 的产物.
Build 的产物中最重要的是三个镜像文件,位于 /out/target/product/<product_name>/ 目录下
ramdisk.img:
                    在启动时将被 Linux 内核挂载为只读分区,它包含了 /init 文件和一些配置文件。
                    它用来挂载其他系统镜像并启动 init 进程。
                     即在源码\system\core\init\init.c文件
system.img:包含了 Android OS 的系统文件,库,可执行文件以及预置的应用程序,将被挂载为根分区。
userdata.img:将被挂载为 /data,包含了应用程序相关的数据以及和用户相关的数据。 
二,android系统的启动流程
1,在init.c文件中有个main( )方法, 有"init_parse_config_file("/init.rc");即解析了这个配置文件
2,我们打开init.rc这个文件,发现其实就是开启service -Xzygote(孵化器;:孵化整个世界)

这个服务启动后启动后了  app_process.cpp,  我们找到这个文件的mian( )方法中
runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
我们继续 探索com.android.internal.os.ZygoteInit.java文件,在其main方法中调用了方法startSystemServer( ),
在这个方法中有一个数组,这个数组中有个类名
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",
即这个方法主要目的是加载了com.android.server.SystemServer.java这个类
ok,我们继续查找这个类中的的main( )方法
我们发现通过JNI调用init1( )方法,init1( )方法的作用就是开启了Native世界

init1( )方法的作用就是开启了Native世界
init2( )方法的作用就是开启了java世界

init1()的代码在源码\frameworks\base\services\jni\com_android_server_SystemServer.cpp
     核心代码在system_init()------->system_init.system_init()
我们继续找到system_init.cpp中的system_init()  至此  把这个Native世界启动起来了,
然后再这个方法中调用了语句:
runtime->callStatic("com/android/server/SystemServer", "init2");
即在启动完Native世界后又启动了java世界

下面我们看一下init2( )方法做了什么事?
1
2
3
4
5
6
public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }

我们在SystemServer.java中找到了ServerThread extends Thread类 
然后我们看一下它的run方法:
ServerThread.run(){
     .....
     Looper.prepare();//
     一大堆的服务和Manager
     Activity Manager
     Package Manager://扫描系统中所有的apk(耗时的操作)
}

下面一张清晰的图来展现:
image


额外的略微看一下Zygote(孵化)进程:
下面篇幅摘自网络博客,原作者和博客地址忘了[抱歉!]
----------------------------------------------------------------------------------------------------------------------------------

Android平台是为手持内嵌设备而设计的,并且大部分手持设备都使用电池工作,其本身拥有的资源非常有限。

所以,手持设备要求内嵌系统平台必须提供一个高效的运行环境,一方面提高设备资源的利用率,另一方面尽可能地加长设备的使用时间。

Android手机用户与设备的交互无非总结为:打开应用以及切换到下一个应用;

为了能有效的减少系统负担,Android在启动新进程(打开新应用)采用了Zygote(孵化)进程。

Init进程系统启动后运行在用户空间的首个进程,init进程启动完系统运行所需要的各种守护进程后,启动Zygote进程

Zygote进程启动后,Android的服务与应用程序都有该进程启动运行。

下面是一个模拟器的进程启动情况,zygote的进程号是33,它的父进程号是1(init进程);

下面的应用的父进程号都是33,说明所有的应用都是由zygote进程生成的。


谷歌在发布Android平台描述平台特性时讲到:

Zygote是Android系统的一个主要特征,通过COW(copy on write)方式对运行在内存中的进程实现了最大程度的复用,并通过库共享有效降低了内存的使用量。

下面来对Zygote进程孵化新进程的过程做进一步了解:

Zygote进程调用fork( )函数创建出Zygote'子进程,子进程Zygote' 共享父进程Zygote的代码区与连接信息。

如下图所示,Fork()橙色箭头左边是Zygote进程,右边是创建出的Zygote‘子进程;

然后Zygote'子进程将执行流程交给应用程序A,Android程序开始运行。

新生成的应用程序A会使用已有Zygote父进程的库与资源的连接信息,所以运行速度很快。

                   

另外,对于上图,Zygote启动后,初始并运行DVM,而后将需要的类与资源加载到内存中。

随后调用fork( )创建出Zygote' 子进程,接着子进程动态加载并运行应用程序A。

运行的应用程序A会使用Zygote已经初始化并启动运行的DVM代码,通过使用已加载至内存中的类与资源来加快运行速度。

以上只是一个抽象的流程,没有具体到代码层的实现,大家如果想分析这部分源代码的话,给大家推荐《Android框架揭秘》这本书。












































  相关解决方案