作为一个Android开发者,开发时总是对于Andorid底层的实现充满了好奇,处于这种强烈的好奇心,我决定到源码中一探究竟,今天就带大家基于源码的角度简单分析一下Android系统从启动到显示出Launcher界面的流程吧!

先来贴一张图,我们就依据这张图,跟到源码中去爽一把!(注意:由于高版本的Android版本太过于复杂和庞大,本文主要基于Android 2.3版本进行分析)

Android启动的顺序

 源码角度分析Android启动流程_第1张图片

 

先来说说常用来看源码的工具Source Insight的使用

Source Insight:

1.    新建源码工程: ProjectàNewproject

源码角度分析Android启动流程_第2张图片

2.    设置工程路径

 源码角度分析Android启动流程_第3张图片

3.    导入源码(最好以Add Tree方式,否则导入会很慢)

源码角度分析Android启动流程_第4张图片

4.    修改文字大小:OptionsàDocumentOptions…àScreen Fonts

导入源码需要注意的问题

具体需要研究那个模块,就将该模块导入

如何导入整个源码:以Add Tree方式


我们进入到正题:

Android启动关键点

当系统引导程序启动Linux内核时, 内核会加载各种数据结构和驱动程序。

有了驱动之后, 开始启动Android系统并加载用户级别的第一个进程:init

 

system/core/init/Init.c:

int main(int argc, char **argv){
 ……

    // 创建各种文件夹和挂载目录.
    mkdir("/dev", 0755);
    ......

    // 初始化日志.
    log_init();
    
    // 解析配置文件.
    init_parse_config_file("/init.rc");

    ...

    return 0;

}

 

加载Init.rc文件, 主要启动了一个Zygote(孵化器)进程,此进程是Android系统启动关键服务的一个母进程。

 

system/core/rootdir/Init.rc:

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 这个C++的程序对应的是App_main.cpp,Zygote进程的初始化在App_main.cpp文件中开启的。

 

frameworks\base\cmds\app_process \App_main.cpp:

int main(int argc, const char* const argv[])
    {
        // 定义Android运行时环境.
        AppRuntime runtime;
        int i = runtime.addVmArguments(argc, argv);
    
        ......
    
        bool startSystemServer = (i < argc) ? 
                strcmp(argv[i], "--start-system-server") == 0 : false;
        setArgv0(argv0, "zygote");
        set_process_name("zygote");

        // 使用运行时环境启动Zygote的初始化类.
        runtime.start("com.android.internal.os.ZygoteInit",
            startSystemServer);
         ......
    }

 

ZygoteInit.java初始化类被调用,其中startSystemServer的值一般均为true,为false会报错。

 

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java:

public static void main(String argv[]) {
            // 加载系统运行依赖的class类.
            preloadClasses();

            ...
            
            if (argv[1].equals("true")) {
                // Zygote孵化器进程开始孵化系统核心服务.
                startSystemServer();
            } else if (!argv[1].equals("false")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }
            
            ...
        }

        private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
            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",
            };

            ...

            // 孵化器分叉开启SystemServer类, 并且把上面定义的参数.
            // 传递给此类. 用于启动系统关键服务.
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        
            ...
        }

 

SystemServer.java被调用,在其main方法中,init1()方法被调用。

 

frameworks\base\services\java\com\android\server\SystemServer.java:

public static void main(String[] args) {
            ...
            
            // 加载本地的动态链接库.
            System.loadLibrary("android_servers");
    
            // 调用动态链接库中的c函数.
            init1(args);
        }
    
   // 这里init1的函数定义在:

// frameworks\base\services\jni\com_android_server_SystemServer.cpp
  native public static void init1(String[] args);

 

Init1()方法是一个C代码实现的方法,其方法实现在com_android_server_SystemServer.cpp下。

 

frameworks\base\services\jni\com_android_server_SystemServer.cpp:

static JNINativeMethod gMethods[] = {
             // 把native方法init1, 映射到android_server_SystemServer_init1

            { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
        };

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

        //
此方法没有方法体.
        extern "C" int system_init();

 

system_init()方法的方法体,在System_init.cpp类中。

 

frameworks\base\cmds\system_server\library\System_init.cpp

extern "C" status_t system_init()
        {
            ......
        
            // 开启一些硬件相关的服务.
            SensorService::instantiate();
            

if (!proc->supportsProcesses()) {

        // Start the AudioFlinger

        AudioFlinger::instantiate();

        // Start the media playback service

        MediaPlayerService::instantiate();

        // Start the camera service

        CameraService::instantiate();

        // Start the audio policy service

        AudioPolicyService::instantiate();

    }
            ......
            
            // 获取Android运行时环境
            AndroidRuntime* runtime = AndroidRuntime::getRuntime();
        
            LOGI("System server: starting Android services.\n");
            // 调用SystemServer类中静态方法init2. 从native层转到java层.
            runtime->callStatic("com/android/server/SystemServer", "init2");
             ......
        }

 

至此,native层面的服务被启动起来了,System_init()在开启完native层面的服务后,又返回去调用SystemServer的init2()方法去了。

 

frameworks\base\services\java\com\android\server\SystemServer.java:

public static final void init2() {
            Slog.i(TAG, "Entered the Android system server!");

            // 进入Android系统服务的初始化.
            Thread thr = new ServerThread();
            thr.setName("android.server.ServerThread");
            thr.start();
 }

 

在init2()方法中,开启了一个ServerThread,ServerThread的run方法中,开启了各种Framework层面的服务,其中,PackageManagerService和ActivityManagerService也是在这个时候被启动的。

 

frameworks\base\services\java\com\android\server\SystemServer.java:

class ServerThread extends Thread {

    ……

    @Override

    public void run() {

        ……

 

        LightsService lights = null;

        PowerManagerService power = null;

        BatteryService battery = null;

        ConnectivityService connectivity = null;

        IPackageManager pm = null;

        Context context = null;

        WindowManagerService wm = null;

        BluetoothService bluetooth = null;

        BluetoothA2dpService bluetoothA2dp = null;

        HeadsetObserver headset = null;

        DockObserver dock = null;

        UsbObserver usb = null;

        UiModeManagerService uiMode = null;

        RecognitionManagerService recognition = null;

        ThrottleService throttle = null;

       

        // 初始化系统的服务, 并且把服务添加ServiceManager中, 便于以后系统进行统一管理

        // Critical services...

        try {

            Slog.i(TAG, "Entropy Service");

            ServiceManager.addService("entropy", new EntropyService());

 

            Slog.i(TAG, "Power Manager");

            power = new PowerManagerService();

            ServiceManager.addService(Context.POWER_SERVICE, power);

 

            ………

}

}

 

至此,Framework层面的服务就都被启动起来了。


 好了,至此,大体流程 我们已经走通了,是不是很酸爽?

下面, 我们再来补充一些细节

Android启动细节

Init进程细节

l  创建文件夹,挂载设备

l  重定向输入输出,如错误信息输出

l  设置日志输出

l  解析和当前设备相关的配置信息(/init.%s.rc)

l  处理动作执行:这个阶段Zygote将被启动

各动作的执行有其自己的优先级:

early-init

Init

early-boot

boot

l  无限循环阶段,等待一些事情发生

 

int main(int argc, char **argv)

{

……

// 创建文件夹,挂载设备

    mkdir("/dev", 0755);

    mkdir("/proc", 0755);

    mkdir("/sys", 0755);

 

    mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");

    mkdir("/dev/pts", 0755);

    mkdir("/dev/socket", 0755);

    mount("devpts", "/dev/pts", "devpts", 0, NULL);

    mount("proc", "/proc", "proc", 0, NULL);

    mount("sysfs", "/sys", "sysfs", 0, NULL);

 

……

// 初始化日志的输入输出

    open_devnull_stdio();

    log_init();

   

    // 加载init.rc配置文件

    init_parse_config_file("/init.rc");

 

   ……

    // 解析和当前设备相关的配置信息

    get_hardware_name(hardware, &revision);

    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);

    init_parse_config_file(tmp);

 

//处理动作执行:这个阶段Zygote将被启动(按优先级执行各动作)

    action_for_each_trigger("early-init", action_add_queue_tail);

……

    action_for_each_trigger("init", action_add_queue_tail);

    ……

    action_for_each_trigger("early-boot", action_add_queue_tail);

    action_for_each_trigger("boot", action_add_queue_tail);

……

// 无限循环阶段,等待一些事情发生

    for(;;) {

        ……

    }

}

 

Init.rc启动细节

l  开启各种守护进程

l  启动app_process

 

……

// 启动守护进程

service servicemanager /system/bin/servicemanager

    user system

    critical

    onrestart restart zygote

onrestart restart media

……

// 启动app_process

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_main实现细节

l  startVM——开启虚拟机(进行堆内存设置)

l  注册JNI函数

l  启动“com.android.internal.os.ZygoteInit”的main方法

 

void AndroidRuntime::start(const char* className, const bool startSystemServer)

{

    ……

// 开启虚拟机,stratVm中调用了:

// property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");来设置堆内存

    /* start the virtual machine */

    if (startVm(&mJavaVM, &env) != 0)

        goto bail;

 

//注册JNI函数

    /*

     * Register android functions.

     */

    if (startReg(env) < 0) {

        LOGE("Unable to register all android natives\n");

        goto bail;

    }

……

// 启动“com.android.internal.os.ZygoteInit”

env->CallStaticVoidMethod(startClass, startMeth, strArray);

……

}

 

ZygoteInit实现细节

l  预加载相应的类preloadClasses()(这个过程大概就要花费20秒,通过反射预加载2000左右个类)

l  预加载资源文件preloadResources()

l  启动SystemServer

 

public static void main(String argv[]) {

        try {

            ……

            // 预加载相应的类

            preloadClasses();

            //预加载资源文件

            preloadResources();

            ……

            // 启动SystemServer

            if (argv[1].equals("true")) {

                startSystemServer();

            } else if (!argv[1].equals("false")) {

                throw new RuntimeException(argv[0] + USAGE_STRING);

            }

        ……

    }

 

注意:

       现在的手机经过不断的优化,预加载类和资源已经用不了20秒这么久,我们大部分的开机时间,其实还是耗在了扫描apk上。

SystemServer实现细节

l  通过init1(),开启native世界

l  通过init2(),开启Framework层的Java世界

l  Init2()开启Framework层时,当PackageMangerService被开启后,它开始扫描监控:

system/framework、 system/app、data/app、data/app-private几个文件夹下的所有apk信息,扫描所有apk权限及四大组件信息,最后找到具有: 

这个过滤器信息的Launcher并启动,完成整个系统的启动


哈哈,怎么样? 是不是get到了新技能,那么下面 我们再来补充一些应用程序启动的细节

 

应用启动详解

PackageManagerService的主要作用

1.    建立 java 层的 installer 与 c 层的installd 的 socket 联接,使得在上层的 install,remove,dexopt等功能最终由 installd 在底层实现

2.    建 立 PackageHandler 消 息 循环 , 用 于 处 理 外 部 的 apk 安 装 请 求 消息 , 如 adbinstall,packageinstaller 安装 apk 时会发送消息 

3.    加载、解析并管理各apk所需的权限信息  

4.    启动 AppDirObserver 线程监测/system/framework,/system/app,/data/app,/data/app-private 目录的事件,主要监听 add 和 remove 事件。

5.    对所有的apk进行逐个的解析(AndroidManifest.xml、assert、res等等…),建立每个APK的配置结构,并将每个apk的信息添加到全局列表

6.    将解析的每个 apk 的信息保存到:data/system/packages.xml、packages.list中。

packages.list 记录了如下数据:pkgName,userId,debugFlag,dataPath(包的数据路径) 

 

PackageManagerService如何识别Launcher应用

PackageManagerService在解析apk的AndroidManifest.xml时,会找到Intent-Filter包含:

 

 

的应用并启动

 

PackageManagerService的桌面图标如何生成

PackageManagerService在解析apk的AndroidManifest.xml时,会找到Intent-Filter包含:

   

       

       

   

的Activity,此Activity即为在桌面上点击图标时,被开启的Activity。


到此,我们已经把Android系统的启动流程 和应用程序启动的流程 分析完了,大家是不是对Android有了新的认识呢? 



更多相关文章

  1. Android中的WebView进行直接加载网页(要注意解决权限问题)
  2. Android设备中几种YUV420p转rgb视频帧方法效率比较
  3. Android Service使用方法--简单音乐播放实例
  4. 从Android 6.0源码的角度剖析View的事件分发机制
  5. Android插件化框架系列之类加载器
  6. Android中Math取整的三个方法
  7. android View的background何时加载的
  8. Android Studio启动时卡在Fetching Android SDK 以及导入Eclipse
  9. Android 资源加载机制剖析

随机推荐

  1. Android(安卓)Studio UI布局
  2. 《Android(安卓)基础(十)》FloatingActionB
  3. Android(安卓)初学入门代码注释 学习笔记
  4. android View onMeasure
  5. android代码实现自动关机
  6. Android中获取电池电量
  7. java android MD5加密
  8. android widget桌面时钟
  9. Android(安卓)Development Notes-2
  10. android WiFi 开关代码