本文是通过学习了卢俊系列博客做的一篇学习记录文章。记录个人觉得比较有用的部分内容,该系列博文主要讲解了Android系统的开机过程和优化的分析处理。最近也在处理开机优化的问题,特此记录之。
repo init -u https://android.googlesource.com/platform/manifest 如果要选择特定版本的Android源码,或者在已下载的源码基础上切换到其他版本,则可以使用-b选项: repo init -u git://git.omapzoom.org/platform/manifest.git -b android-5.0.2_r1 然后使用repo sync同步代码 repo sync
上面提到了repo init需要初始化一个manifest仓库,仓库中含有一个很重要的manifest.xml文件清单,其实这个manifest.xml并不复杂的,它就是用XML文件的格式记录了本项目依赖的各个Git仓库的名称、地址,以及分支等信息。常用的元素如下所示:
manifest 最顶层的XML元素remote 设置远程git服务器的属性,如名称、根URL地址等PRoject 需要clone的Git仓库,path表示本机路径,name表示远程版本库的相对路径copyfile 执行拷贝操作,把URL/查看android源码分支和版本
git –git-dir .repo/manifests/.git/ branch -a
或者
cd .repo/manifests git branch -a | cut -d / -f 3
如果要切换的其他分支,执行下面的命令即可
repo init -b android-4.2.2_r1 repo sync
主要分析下init程序,它是分析Android启动过程中最核心的程序。 代码路径:system/core/init/init.c init程序最核心的工作主要有3点: 1. 创建和挂载一些系统目录/设备节点,设置权限,如:/dev, /proc, and /sys 2. 解析 init.rc 和 init.hardware.rc,并启动属性服务,以及一系列的服务和进程。 3. 显示boot logo,默认是“Android”字样
最重要的是第二步,这个过程中会启动系统所需功能的各种服务。主要分为本地服务和Android服务,它们都会在ServiceManager中进行注册。
本地服务 本地服务是指运行在C++层的系统守护进程,一部分有init进程直接启动,它们定义在init.rc脚本中,还有一部分本地服务是由这些本地服务启动,如果mediaserver服务会启动AudioFlinger,MediaPlayerService,以及CameraService等本地服务。 每一个由init直接启动的本地服务都是一个独立的linux进程,可以通过adb shell top查看相应的进程。Android服务 Android服务是指运行在Dalvik虚拟机进程中的服务。 init进程会执行app_process程序,创建Zygote进程,它是Android系统最重要的进程,后续所有的Android应用程序都是由它fork出来的。 Zygote进程会先fork出SystemServer进程,SystemServer进程就会启动所有的Android核心服务。例如:Activity Manager、Window Manager、Power Manager等等服务。当所服务启动完毕后,SystemServer会打印出”Making services ready”,然后通过Activity Manager启动Home界面,并发送“ACTION_BOOT_COMPLETED”广播消息。 SystemServer进程添加的服务都属于SystemServer进程。下图为Android系统启动过程: 
2个概念:
Android是基于Linux内核的系统,因此Android的启动过程是分为两个阶段的,第一个阶段就是Linux内核的启动,第二个阶段就是Android框架的启动(包括核心服务和程序)。
Android的log系统是独立于Linux内核的log系统的。Linux内核通过printk打印的log信息,这些log写入到了/dev/kmsg文件中,在Shell终端可以通过dmesg命令查看这些log信息。Android框架则是通过Logger驱动打印log信息,这些log并没有归并到kmesg文件中,而是单独存储的,位于/dev/log目录下,在Shell终端可以通过logcat命令来查看。
通过dmesg命令抓取Linux内核的log信息
adb shell dmesg > D:/dmesg.txt
Android系统把Log分为了四类,不同的类别记录不同的Log信息:
main - 主要的Log信息,大部分应用级别的Log信息都在这里 events - 系统事件相关的Log信息 radio - 无线/电话相关的Log信息 system - 低级别的系统调试Log信息
logcat默认抓取的是main信息,如果想抓取指定类别的log信息的方法,在logcat命令后加-b参数,例如:
$ adb logcat -d -v time -b "main" > D:/main.txt$ adb logcat -d -v time -b "events" > D:/events.txt$ adb logcat -d -v time -b "system" > D:/system.txt$ adb logcat -d -v time -b "radio" > D:/radio.txt查看系统启动时间
adb logcat -d -b events | grep “boot”

通过dmesg抓取log信息
adb shell dmesg > D:/dmesg.txt
在dmesg.txt中搜索几个关键字 Zygote、system_server、mediaserver等关键字可以获取相关模块的开机耗时信息。
Android系统的启动优化主要分为三大部分: 1. Bootloader优化 2. Linux Kernel的剪裁与优化 3. Android OS部分的剪裁与优化
下面主要讲Android os部分的优化 1. 精简preload的classes和resource frameworks/base/preload-classes frameworks/base/core/res/res/values/arrays.xml 2. 精简native service和java service system/core/rootdir/init.rc frameworks/base/services/java/com/android/server/SystemServer.java 3. 精简预装的apk文件 build/target/product/xxxx.mk device///xxxx.mk vendor/…./xxxx.mk 4. 减少内核的log打印级别 system/core/rootdir/init.rc 5. 其他优化手段 - 优化启动动画,降低帧率和图片尺寸 - 精简系统,减小boot.img文件大小,可以显著减少启动过程中加载和解压boot.img的时间 - 预先创建一些目录和文件,而不是在init过程中创建
JNI目录下的Android.mk文件(假设jni目录下有inc和src目录)
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := libmynativeLOCAL_SRC_FILES := src/mynative.cLOCAL_C_INCLUDES += $(JNI_H_INCLUDE)LOCAL_C_INCLUDES += $(LOCAL_PATH)/incinclude $(BUILD_SHARED_LIBRARY)含有jni本地代码,并且本地代码依赖第三方库(.a或者so) 假设本地代码依赖的第三方库为:encoder.a 和 decoder.so
修改上述jni目录下的Android.mk
LOCAL_STATIC_LIBRARIES := libencoderLOCAL_SHARED_LIBRARIES := libdecoder修改HelloWorld目录下的Android.mk文件(encoder.a 和 decoder.so 都拷贝到工程根目录)
include $(CLEAR_VARS)LOCAL_MODULE := libencoderLOCAL_SRC_FILES := encoder.aLOCAL_MODULE_TAGS := engLOCAL_MODULE_CLASS := STATIC_LIBRARIESLOCAL_MODULE_SUFFIX := .ainclude $(BUILD_PREBUILT)include $(CLEAR_VARS)LOCAL_MODULE := libdecoderLOCAL_SRC_FILES := decoder.soLOCAL_MODULE_TAGS := engLOCAL_MODULE_CLASS := SHARED_LIBRARIESLOCAL_MODULE_SUFFIX := .soinclude $(BUILD_PREBUILT)新闻热点
疑难解答