Source Insight:
1. 新建源码工程: ProjectàNewproject
2. 设置工程路径
3. 导入源码(最好以Add Tree方式,否则导入会很慢)
4. 修改文字大小:OptionsàDocumentOptions…àScreen Fonts
具体需要研究那个模块,就将该模块导入
如何导入整个源码:以Add Tree方式
当系统引导程序启动Linux内核时, 内核会加载各种数据结构和驱动程序。
有了驱动之后, 开始启动Android系统并加载用户级别的第一个进程:init
system/core/init/Init.c:
int main(int argc, char **argv){ } |
加载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[]) |
ZygoteInit.java初始化类被调用,其中startSystemServer的值一般均为true,为false会报错。
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java:
public static void main(String argv[]) { |
SystemServer.java被调用,在其main方法中,init1()方法被调用。
frameworks\base\services\java\com\android\server\SystemServer.java:
public static void main(String[] args) { // frameworks\base\services\jni\com_android_server_SystemServer.cpp下 |
Init1()方法是一个C代码实现的方法,其方法实现在com_android_server_SystemServer.cpp下。
frameworks\base\services\jni\com_android_server_SystemServer.cpp:
static JNINativeMethod gMethods[] = { { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 }, |
system_init()方法的方法体,在System_init.cpp类中。
frameworks\base\cmds\system_server\library\System_init.cpp
extern "C" status_t system_init() 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(); } |
至此,native层面的服务被启动起来了,System_init()在开启完native层面的服务后,又返回去调用SystemServer的init2()方法去了。
frameworks\base\services\java\com\android\server\SystemServer.java:
public static final void init2() { |
在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层面的服务就都被启动起来了。
好了,至此,大体流程 我们已经走通了,是不是很酸爽?
下面, 我们再来补充一些细节
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(;;) { …… } } |
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 …… |
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); …… } |
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上。
l 通过init1(),开启native世界
l 通过init2(),开启Framework层的Java世界
l Init2()开启Framework层时,当PackageMangerService被开启后,它开始扫描监控:
system/framework、 system/app、data/app、data/app-private几个文件夹下的所有apk信息,扫描所有apk权限及四大组件信息,最后找到具有:
这个过滤器信息的Launcher并启动,完成整个系统的启动
哈哈,怎么样? 是不是get到了新技能,那么下面 我们再来补充一些应用程序启动的细节
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在解析apk的AndroidManifest.xml时,会找到Intent-Filter包含:
|
的应用并启动
PackageManagerService在解析apk的AndroidManifest.xml时,会找到Intent-Filter包含:
|
的Activity,此Activity即为在桌面上点击图标时,被开启的Activity。
到此,我们已经把Android系统的启动流程 和应用程序启动的流程 分析完了,大家是不是对Android有了新的认识呢?