源码角度分析Android启动流程

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

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

Android启动的顺序

 

 

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

Source Insight:

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


2.    设置工程路径

 

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


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权限及四大组件信息,最后找到具有: 

<category android:name="android.intent.category.HOME"/>

这个过滤器信息的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包含:

 

<category android:name="android.intent.category.HOME" />

 

的应用并启动

 

PackageManagerService的桌面图标如何生成

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

    <intent-filter>

        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />

    </intent-filter>

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


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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值