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.%s.rc)
-
处理动作执行:这个阶段Zygote将被启动
各动作的执行有其自己的优先级: early-init Init early-boot boot
无限循环阶段,等待一些事情发生
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启动细节
开启各种守护进程
启动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实现细节
startVM——开启虚拟机(进行堆内存设置)
注册JNI函数
启动“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实现细节
预加载相应的类preloadClasses()(这个过程大概就要花费20秒,通过反射预加载2000左右个类)
预加载资源文件preloadResources()
启动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实现细节
通过init1(),开启native世界
通过init2(),开启Framework层的Java世界
-
Init2()开启Framework层时,当PackageMangerService被开启后,它开始扫描监控:
system/framework、 system/app、data/app、data/app-private几个文件夹下的所有apk信息,扫描所有apk权限及四大组件信息,最后找到具有: <category android:name="android.intent.category.HOME" /> 这个过滤器信息的Launcher并启动,完成整个系统的启动
应用启动详解
PackageManagerService的主要作用
建立 java 层的 installer 与 c 层的 installd 的 socket 联接,使得在上层的 install,remove,dexopt等功能最终由 installd 在底层实现
建 立 PackageHandler 消 息 循 环 , 用 于 处 理 外 部 的 apk 安 装 请 求 消 息 , 如 adbinstall,packageinstaller 安装 apk 时会发送消息
加载、解析并管理各apk所需的权限信息
启动 AppDirObserver 线程监测/system/framework,/system/app,/data/app,/data/app-private 目录的事件,主要监听 add 和 remove 事件。
对所有的apk进行逐个的解析(AndroidManifest.xml、assert、res等等…),建立每个APK的配置结构,并将每个apk的信息添加到全局列表
-
将解析的每个 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。
应用程序启动的入口类是哪个?
ActivityThread是主要用来启动应用程序的主线程,并且管理在应用端跟用户打交道的activity,管理各组件的生命周期。
frameworks\base\core\java\android\app\ ActivityThread.java
public static final void main(String[] args) {
……
// ActivityThread其实就是我们经常说的UI thread,也就是主线程。
// 主线程可以使用Handler进行异步通信,因为主线程中已经创建了Looper,而这个Looper就是在这里创建的。如果其他线程需要使用Handler通信,就要自己去创建Looper
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
……
}
/** 将进行启动activity的相关工作 */
private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
……
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward);
……
}
}
/** 进行了一些初始化和赋值操作后,创建activity,并调用其onCreate方法*/
private final Activity performLaunchActivity(ActivityClientRecord r,
Intent customIntent) {
……
Activity activity = null;
……
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
……
if (activity != null) {
……
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstance,
r.lastNonConfigurationChildInstances, config);
// 开始调用acitivity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
……
}
……
return activity;
}
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
……
ActivityClientRecord r = performResumeActivity(token, clearHide);
}
/** H负责处理ApplicationThread发送到消息队列的消息 */
private final class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
……
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo);
handleLaunchActivity(r, null);
} break;
……
}
……
}