第四章 Android启动过程的上层实现

Android中有两个世界,一个是Java世界,一个是Native世界。第三章介绍的是native世界的启动,那么java世界是什么时候启动的呢?还记得在解析完init.rc文件之后启动很多的服务,其中非常重要的两个服务就是zygote和servicemanager。其中zygote就是android世界的第一个虚拟机,在android中扮演非常重要的角色,下面讨论的内容就是android启动剩下的流程,先看一个android上层启动的流程:

1 ini进程在解析完init.rc文件之后启动了一个非常重要的守护服务zygote,它是android的第一个虚拟机

2 zygote创建一个socket,和AMS进行通信

3 zygote通过fork创建进程system_server进程

4 system_server中的init1启动native system service,init2阶段启动java system_service

5 系统服务启动之后注册到servicemanager中

6 AMS进入systemReady状态

7 AMS和zygote创建的socket进行socket通信,请求启动HOME

8 zygote收到AMS的请求之后执行runSelectLoopMode处理请求

9 通过forkAndSepcialize启动新进程,最终启动Home应用

4.1zygote 

zygote是孵化器,受精卵的意思。android的app都是运行在一个独立的dalvik虚拟机之中,如果每个app都要初始化一个dalvik虚拟机会浪费很多资源降低性能,所以android先创建一个zygote虚拟机,通过它来孵化启动的虚拟机,进而共享虚拟机内存和框架层资源,提高app启动速度和运行速度。

4.1.1 zygote Service的配置信息

先看在init.rc中zygote Service的配置:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

#class基本是main,还记得service是通过这个Action来启动的吗?

class main

#创建一个socket通信

socket zygote stream 666

#如果zygote服务重启时执行的command操作

onrestart write /sys/android_power/request_state wake

onrestart write /sys/power/state on

onrestart restart media

onrestart restart netd

名称为zygote,程序路径为 /system/bin/app_process,参数为-Xzygote /system/bin --zygote --start-system-server。下面都是option,创建一个socket用户通信,如果zygote服务重启执行write /sys/android_power/request_state wake, write /sys/power/state on, restart media,restart netd四个command。关于Service和Command请看第三章内容

4.1.2如何执行zygote服务

zygote对应的程序名称是app_process,对应的文件程序时frameworks/base/cmds/app_process/App_main.cpp文件中,直接看它的main函数:

int main(int argc, const char* const argv[])

{

//参数为-Xzygote /system/bin --zygote --start-system-server

// These are global variables in ProcessState.cpp

mArgC = argc;

mArgV = argv;

mArgLen = 0;

for (int i=0; i<argc; i++) {

mArgLen += strlen(argv[i]) + 1;

}

mArgLen--;

AppRuntime runtime;//它是AndroidRuntime的子类

const char* argv0 = argv[0];

// Process command line arguments

// ignore argv[0]

argc--;

argv++;

// Everything up to ‘--‘ or first non ‘-‘ arg goes to the vm

int i = runtime.addVmArguments(argc, argv);

// Parse runtime arguments.  Stop at first unrecognized option.

bool zygote = false;

bool startSystemServer = false;

bool application = false;

const char* parentDir = NULL;

const char* niceName = NULL;

const char* className = NULL;

while (i < argc) {

const char* arg = argv[i++];

if (!parentDir) {

parentDir = arg;//将/system/bin 保存到parentDir 中

} else if (strcmp(arg, "--zygote") == 0) {//

zygote = true;//如果在参数中指定了--zygote,设置zygote为true,并修改niceName为"zygote"

niceName = "zygote";

} else if (strcmp(arg, "--start-system-server") == 0) {

startSystemServer = true;////如果设置了--start-system-server"

} else if (strcmp(arg, "--application") == 0) {

application = true;//如果启动了--application

} else if (strncmp(arg, "--nice-name=", 12) == 0) {

niceName = arg + 12;//如果指定了nicename

} else {

className = arg;

break;

}

}

if (niceName && *niceName) {

//修改进程名称为zygote

setArgv0(argv0, niceName);

set_process_name(niceName);

}

runtime.mParentDir = parentDir;

if (zygote) {//这里zygote为true,所以执行这个,最主要功能在这里完成

runtime.start("com.android.internal.os.ZygoteInit",

startSystemServer ? "start-system-server" : "");

} else if (className) {

// Remainder of args get passed to startup class main()

runtime.mClassName = className;

runtime.mArgC = argc - i;

runtime.mArgV = argv + i;

runtime.start("com.android.internal.os.RuntimeInit",

application ? "application" : "tool");

} else {

fprintf(stderr, "Error: no class name or --zygote supplied.\n");

app_usage();

LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");

return 10;

}

}

4.2 zygoteInit的启动过程

接下来看AppRuntime的start方法,AppRuntime是继承AndroidRuntime的start方法,直接看AndroidRuntime的start方法,在frameworks/base/core/jni/AndroidRuntime.cpp文件中

/*

* Start the Android runtime.  This involves starting the virtual machine

* and calling the "static void main(String[] args)" method in the class

* named by "className".

*

* Passes the main function two arguments, the class name and the specified

* options string.

*/

void AndroidRuntime::start(const char* className, const char* options)

{

//className是com.android.internal.os.ZygoteInit

//options 是startSystemServer ? "start-system-server" : ""

...

阻塞信号

blockSigpipe();

/*

* ‘startSystemServer == true‘ means runtime is obsolete and not run from

* init.rc anymore, so we print out the boot start event here.

*/

if (strcmp(options, "start-system-server") == 0) {

/* track our progress through the boot sequence */

const int LOG_BOOT_PROGRESS_START = 3000;

LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,

ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));

}

.....

/* start the virtual machine */

JNIEnv* env;

//1.开启虚拟机

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

return;

}

//初始化虚拟机内容

onVmCreated(env);

/*

* Register android functions.

*/

//2.注册andriod的JNI函数

if (startReg(env) < 0) {

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

return;

}

/*

* We want to call main() with a String array with arguments in it.

* At present we have two arguments, the class name and an option string.

* Create an array to hold them.

*/

jclass stringClass;

jobjectArray strArray;

jstring classNameStr;

jstring optionsStr;

stringClass = env->FindClass("java/lang/String");

assert(stringClass != NULL);

//创建一个两个元素的String数组

strArray = env->NewObjectArray(2, stringClass, NULL);

assert(strArray != NULL);

//classNameStr="com.android.internal.os.ZygoteInit"

classNameStr = env->NewStringUTF(className);

assert(classNameStr != NULL);

env->SetObjectArrayElement(strArray, 0, classNameStr);

//optionsStr="true"

optionsStr = env->NewStringUTF(options);

env->SetObjectArrayElement(strArray, 1, optionsStr);

/*

* Start VM.  This thread becomes the main thread of the VM, and will

* not return until the VM exits.

*/

将com.android.internal.os.ZygoteInit 转换为com/android/internal/os/ZygoteInit

char* slashClassName = toSlashClassName(className);

jclass startClass = env->FindClass(slashClassName);

if (startClass == NULL) {

LOGE("JavaVM unable to locate class ‘%s‘\n", slashClassName);

/* keep going */

} else {

//找到com/android/internal/os/ZygoteInit  的main函数

jmethodID startMeth = env->GetStaticMethodID(startClass, "main",

"([Ljava/lang/String;)V");

if (startMeth == NULL) {

LOGE("JavaVM unable to find main() in ‘%s‘\n", className);

/* keep going */

} else {

//3.通过JNIEnv启动zygoteInit的卖弄函数,并传入阐述参数strArray

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

#if 0

if (env->ExceptionCheck())

threadExitUncaughtException(env);

#endif

}

}

//释放资源

free(slashClassName);

}

一共做了三个主要工作:1 通过startVm创建虚拟机;2 通过startReg注册JNI方法;3 调用java层ZygoteInit 的main方法

4.2.1创建虚拟机

AndroidRuntime中start方法的第一步就是创建dalvik虚拟机,看startVm方法

/*

* Start the Dalvik Virtual Machine.

*

* Various arguments, most determined by system properties, are passed in.

* The "mOptions" vector is updated.

*

* Returns 0 on success.

*/

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)

{

int result = -1;

JavaVMInitArgs initArgs;

JavaVMOption opt;

//1.读取属性配置并设置虚拟机参数

//是否配置checkjni

property_get("dalvik.vm.checkjni", propBuf, "");

property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");

property_get("dalvik.vm.check-dex-sum", propBuf, "");

....

/*

* Initialize the VM.

*

* The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.

* If this call succeeds, the VM is ready, and we can start issuing

* JNI calls.

*/

//2.调用JNI_CreateJavaVM 函数创建虚拟机

if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {

LOGE("JNI_CreateJavaVM failed\n");

goto bail;

}

result = 0;

bail:

free(stackTraceFile);

return result;

}

做了两个操作:1 读取配置信息并设置虚拟机参数;2 启动虚拟机

4.2.2注册JNI方法

AndroidRuntime中start方法的第二步就是通过startReg注册JNI方法,这些注册的JNI函数是java世界调用native函数的基础,非常重要,看startReg方法:

/*

* Register android native functions with the VM.

*/

/*static*/ int AndroidRuntime::startReg(JNIEnv* env)

{

/*

* This hook causes all future threads created in this process to be

* attached to the JavaVM.  (This needs to go away in favor of JNI

* Attach calls.)

*/

androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

LOGV("--- registering native functions ---\n");

env->PushLocalFrame(200);

//核心功能是在register_jni_procs 函数

if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {

env->PopLocalFrame(NULL);

return -1;

}

env->PopLocalFrame(NULL);

//createJavaThread("fubar", quickTest, (void*) "hello");

return 0;

}

其中gRegJNI是一个结构体为RegJNIRec数组,RegJNIRec的定义是:

#ifdef NDEBUG

#define REG_JNI(name)      { name }

struct RegJNIRec {

int (*mProc)(JNIEnv*);//一个函数指针

};

#else

#define REG_JNI(name)      { name, #name }

struct RegJNIRec {

int (*mProc)(JNIEnv*);

const char* mName;

};

#endif

gRegJNI数组:

static const RegJNIRec gRegJNI[] = {

REG_JNI(register_android_debug_JNITest),

REG_JNI(register_com_android_internal_os_RuntimeInit),

REG_JNI(register_android_os_SystemClock),

REG_JNI(register_android_util_EventLog),

REG_JNI(register_android_util_Log),

REG_JNI(register_android_util_FloatMath),

REG_JNI(register_android_text_format_Time),

REG_JNI(register_android_content_AssetManager),

REG_JNI(register_android_content_StringBlock),

REG_JNI(register_android_content_XmlBlock),

REG_JNI(register_android_emoji_EmojiFactory),

REG_JNI(register_android_text_AndroidCharacter),

REG_JNI(register_android_text_AndroidBidi),

REG_JNI(register_android_text_KeyCharacterMap),

REG_JNI(register_android_os_Process),

REG_JNI(register_android_os_SystemProperties),

REG_JNI(register_android_os_Binder),

REG_JNI(register_android_view_Display),

REG_JNI(register_android_nio_utils),

REG_JNI(register_android_graphics_PixelFormat),

REG_JNI(register_android_graphics_Graphics),

REG_JNI(register_android_view_GLES20Canvas),

REG_JNI(register_android_view_Surface),

REG_JNI(register_android_view_TextureView),

REG_JNI(register_com_google_android_gles_jni_EGLImpl),

REG_JNI(register_com_google_android_gles_jni_GLImpl),

REG_JNI(register_android_opengl_jni_GLES10),

REG_JNI(register_android_opengl_jni_GLES10Ext),

REG_JNI(register_android_opengl_jni_GLES11),

REG_JNI(register_android_opengl_jni_GLES11Ext),

REG_JNI(register_android_opengl_jni_GLES20),

REG_JNI(register_android_graphics_Bitmap),

REG_JNI(register_android_graphics_BitmapFactory),

REG_JNI(register_android_graphics_BitmapRegionDecoder),

REG_JNI(register_android_graphics_Camera),

REG_JNI(register_android_graphics_Canvas),

REG_JNI(register_android_graphics_ColorFilter),

REG_JNI(register_android_graphics_DrawFilter),

REG_JNI(register_android_graphics_Interpolator),

REG_JNI(register_android_graphics_LayerRasterizer),

REG_JNI(register_android_graphics_MaskFilter),

REG_JNI(register_android_graphics_Matrix),

REG_JNI(register_android_graphics_Movie),

REG_JNI(register_android_graphics_NinePatch),

REG_JNI(register_android_graphics_Paint),

REG_JNI(register_android_graphics_Path),

REG_JNI(register_android_graphics_PathMeasure),

REG_JNI(register_android_graphics_PathEffect),

REG_JNI(register_android_graphics_Picture),

REG_JNI(register_android_graphics_PorterDuff),

REG_JNI(register_android_graphics_Rasterizer),

REG_JNI(register_android_graphics_Region),

REG_JNI(register_android_graphics_Shader),

REG_JNI(register_android_graphics_SurfaceTexture),

REG_JNI(register_android_graphics_Typeface),

REG_JNI(register_android_graphics_Xfermode),

REG_JNI(register_android_graphics_YuvImage),

REG_JNI(register_android_database_CursorWindow),

REG_JNI(register_android_database_SQLiteCompiledSql),

REG_JNI(register_android_database_SQLiteDatabase),

REG_JNI(register_android_database_SQLiteDebug),

REG_JNI(register_android_database_SQLiteProgram),

REG_JNI(register_android_database_SQLiteQuery),

REG_JNI(register_android_database_SQLiteStatement),

REG_JNI(register_android_os_Debug),

REG_JNI(register_android_os_FileObserver),

REG_JNI(register_android_os_FileUtils),

REG_JNI(register_android_os_MessageQueue),

REG_JNI(register_android_os_ParcelFileDescriptor),

REG_JNI(register_android_os_Power),

REG_JNI(register_android_os_StatFs),

REG_JNI(register_android_os_UEventObserver),

REG_JNI(register_android_net_LocalSocketImpl),

REG_JNI(register_android_net_NetworkUtils),

REG_JNI(register_android_net_TrafficStats),

REG_JNI(register_android_net_wifi_WifiManager),

REG_JNI(register_android_nfc_NdefMessage),

REG_JNI(register_android_nfc_NdefRecord),

REG_JNI(register_android_os_MemoryFile),

REG_JNI(register_com_android_internal_os_ZygoteInit),

REG_JNI(register_android_hardware_Camera),

REG_JNI(register_android_hardware_SensorManager),

REG_JNI(register_android_hardware_UsbDevice),

REG_JNI(register_android_hardware_UsbDeviceConnection),

REG_JNI(register_android_hardware_UsbRequest),

REG_JNI(register_android_media_AudioRecord),

REG_JNI(register_android_media_AudioSystem),

REG_JNI(register_android_media_AudioTrack),

REG_JNI(register_android_media_JetPlayer),

REG_JNI(register_android_media_ToneGenerator),

REG_JNI(register_android_opengl_classes),

REG_JNI(register_android_bluetooth_HeadsetBase),

REG_JNI(register_android_bluetooth_BluetoothAudioGateway),

REG_JNI(register_android_bluetooth_BluetoothSocket),

REG_JNI(register_android_server_BluetoothService),

REG_JNI(register_android_server_BluetoothEventLoop),

REG_JNI(register_android_server_BluetoothA2dpService),

REG_JNI(register_android_server_NetworkManagementSocketTagger),

REG_JNI(register_android_server_Watchdog),

REG_JNI(register_android_ddm_DdmHandleNativeHeap),

REG_JNI(register_android_backup_BackupDataInput),

REG_JNI(register_android_backup_BackupDataOutput),

REG_JNI(register_android_backup_FileBackupHelperBase),

REG_JNI(register_android_backup_BackupHelperDispatcher),

REG_JNI(register_android_app_backup_FullBackup),

REG_JNI(register_android_app_ActivityThread),

REG_JNI(register_android_app_NativeActivity),

REG_JNI(register_android_view_InputChannel),

REG_JNI(register_android_view_InputQueue),

REG_JNI(register_android_view_KeyEvent),

REG_JNI(register_android_view_MotionEvent),

REG_JNI(register_android_view_PointerIcon),

REG_JNI(register_android_view_VelocityTracker),

REG_JNI(register_android_content_res_ObbScanner),

REG_JNI(register_android_content_res_Configuration),

REG_JNI(register_android_animation_PropertyValuesHolder),

REG_JNI(register_com_android_internal_content_NativeLibraryHelper),

};

上面结构体定义的函数中最终都调用了jniRegisterNativeMethods函数注册。

如register_android_debug_JNITest

int register_android_debug_JNITest(JNIEnv* env)

{

return jniRegisterNativeMethods(env, "android/debug/JNITest",

gMethods, NELEM(gMethods));

}

如register_com_android_internal_os_RuntimeInit

int register_com_android_internal_os_RuntimeInit(JNIEnv* env)

{

return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",

gMethods, NELEM(gMethods));

}

调用了register_jni_procs:

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)

{

for (size_t i = 0; i < count; i++) {

//调用数组元素的mProc 函数

if (array[i].mProc(env) < 0) {

#ifndef NDEBUG

LOGD("----------!!! %s failed to load\n", array[i].mName);

#endif

return -1;

}

}

return 0;

}

上面完成中重要的JNI函数的注册,下面就是启动ZygoteInit

4.2.3调用java层ZygoteInit 的main方法

调用frameworks/base/java/com/android/internal/os/ZygoteInit.java中的main方法:

public static void main(String argv[]) {

try {

// Start profiling the zygote initialization.

SamplingProfilerIntegration.start();

// 1.注册zygote所需的socket,AMS可以通信启动新的app程序

registerZygoteSocket();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,

SystemClock.uptimeMillis());

// 2.加载class资源和resource资源 ,共享框架层资源,提高效率

preload();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,

SystemClock.uptimeMillis());

// Finish profiling the zygote initialization.

SamplingProfilerIntegration.writeZygoteSnapshot();

// Do an initial gc to clean up after startup

gc();

// If requested, start system server directly from Zygote

if (argv.length != 2) {

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

}

if (argv[1].equals("start-system-server")) {

// 3 启动systemserver,启动native system service和java system service

startSystemServer();

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

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

}

Log.i(TAG, "Accepting command socket connections");

if (ZYGOTE_FORK_MODE) {//ZYGOTE_FORK_MODE 为false

runForkMode();

} else {

// 4.runSelectLoopMode

runSelectLoopMode();//处理新的请求

}

closeServerSocket();

} catch (MethodAndArgsCaller caller) {

// 5 执行MethodAndArgsCaller的run方法

caller.run();

} catch (RuntimeException ex) {

Log.e(TAG, "Zygote died with exception", ex);

closeServerSocket();

throw ex;

}

}

zygote做的工作主要有:

1.注册zygote所需的socket,AMS可以通信启动新的app程序

2.加载class资源和resource资源 ,共享框架层资源,提高效率

3.启动systemserver,启动native system service和java system service

4.runSelectLoopMode

5.执行MethodAndArgsCaller的run方法

4.3 zygoteInit做的五个工作

4.3.1 注册zygote的Socket

通过函数registerZygoteSocket实现:

/**

* Registers a server socket for zygote command connections

* @throws RuntimeException when open fails

*/

private static void registerZygoteSocket() {

if (sServerSocket == null) {

int fileDesc;

try {

String env = System.getenv(ANDROID_SOCKET_ENV);

fileDesc = Integer.parseInt(env);

} catch (RuntimeException ex) {

throw new RuntimeException(

ANDROID_SOCKET_ENV + " unset or invalid", ex);

}

try {

//创建一个socket,和AMS通信

sServerSocket = new LocalServerSocket(

createFileDescriptor(fileDesc));

} catch (IOException ex) {

throw new RuntimeException(

"Error binding to local socket ‘" + fileDesc + "‘", ex);

}

}

}

创建socket,该socket可以和AMS通信,android启动新进场的通道就是这个socket

4.3.2 预加载class和resource

调用preload方法:

static void preload() {

preloadClasses();

preloadResources();

}

分别调用preloadClasses和preloadResource加载资源

preloadClasses方法

/**

* Performs Zygote process initialization. Loads and initializes

* commonly used classes.

*

* Most classes only cause a few hundred bytes to be allocated, but

* a few will allocate a dozen Kbytes (in one case, 500+K).

*/

private static void preloadClasses() {

final VMRuntime runtime = VMRuntime.getRuntime();

//PRELOADED_CLASSES 为preloaded-classes

InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(

PRELOADED_CLASSES);

if (is == null) {

Log.e(TAG, "Couldn‘t find " + PRELOADED_CLASSES + ".");

} else {

Log.i(TAG, "Preloading classes...");

long startTime = SystemClock.uptimeMillis();

// Drop root perms while running static initializers.

setEffectiveGroup(UNPRIVILEGED_GID);

setEffectiveUser(UNPRIVILEGED_UID);

// Alter the target heap utilization.  With explicit GCs this

// is not likely to have any effect.

float defaultUtilization = runtime.getTargetHeapUtilization();

runtime.setTargetHeapUtilization(0.8f);

// Start with a clean slate.

System.gc();

runtime.runFinalizationSync();

Debug.startAllocCounting();

try {

BufferedReader br= new BufferedReader(new InputStreamReader(is), 256);

int count = 0;

String line;

while ((line = br.readLine()) != null) {

// Skip comments and blank lines.

line = line.trim();

if (line.startsWith("#") || line.equals("")) {

continue;

}

try {

if (false) {

Log.v(TAG, "Preloading " + line + "...");

}

//使用java中的反射机制加载class文件

Class.forName(line);

if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {

System.gc();

runtime.runFinalizationSync();

Debug.resetGlobalAllocSize();

}

count++;

} catch (ClassNotFoundException e) {

Log.w(TAG, "Class not found for preloading: " + line);

} catch (Throwable t) {

Log.e(TAG, "Error preloading " + line + ".", t);

if (t instanceof Error) {

throw (Error) t;

}

if (t instanceof RuntimeException) {

throw (RuntimeException) t;

}

throw new RuntimeException(t);

}

}

Log.i(TAG, "...preloaded " + count + " classes in "

+ (SystemClock.uptimeMillis()-startTime) + "ms.");

} catch (IOException e) {

Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);

} finally {

IoUtils.closeQuietly(is);

// Restore default.

runtime.setTargetHeapUtilization(defaultUtilization);

Debug.stopAllocCounting();

// Bring back root. We‘ll need it later.

setEffectiveUser(ROOT_UID);

setEffectiveGroup(ROOT_GID);

}

}

}

该函数的作用就是加载preloaded-classes文件中的类,此文件在frameworks/base目录下,内容很多:

# Classes which are preloaded by com.android.internal.os.ZygoteInit.

# Automatically generated by frameworks/base/tools/preload/WritePreloadedClassFile.java.

# MIN_LOAD_TIME_MICROS=1250

# MIN_PROCESSES=10

android.R$styleable

android.accounts.Account

.....

一共有2000多行的类要加载

preloadResource方法

/**

* Load in commonly used resources, so they can be shared across

* processes.

*

* These tend to be a few Kbytes, but are frequently in the 20-40K

* range, and occasionally even larger.

*/

private static void preloadResources() {

final VMRuntime runtime = VMRuntime.getRuntime();

Debug.startAllocCounting();

try {

System.gc();

runtime.runFinalizationSync();

mResources = Resources.getSystem();

mResources.startPreloading();

//PRELOAD_RESOURCES 默认为true

if (PRELOAD_RESOURCES) {

Log.i(TAG, "Preloading resources...");

long startTime = SystemClock.uptimeMillis();

TypedArray ar = mResources.obtainTypedArray(com.android.internal.R.array.preloaded_drawables);

//加载com.android.internal.R.array.preloaded_drawables

int N = preloadDrawables(runtime, ar);

startTime = SystemClock.uptimeMillis();

ar = mResources.obtainTypedArray(com.android.internal.R.array.preloaded_color_state_lists);

//加载com.android.internal.R.array.preloaded_color_state_lists

N = preloadColorStateLists(runtime, ar);

}

mResources.finishPreloading();

} catch (RuntimeException e) {

Log.w(TAG, "Failure preloading resources", e);

} finally {

Debug.stopAllocCounting();

}

}

4.3.3 启动systemserver

通过函数startSystemServer来启动systemserver:

/**

* Prepare the arguments and fork for the system server process.

*/

private static boolean startSystemServer()

throws MethodAndArgsCaller, RuntimeException {

/* Hardcoded command line to start the system server */

String args[] = {

"--setuid=1000",//设置uid,gid等参数

"--setgid=1000",

"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",

"--capabilities=130104352,130104352",

"--runtime-init",

"--nice-name=system_server",//进程名称为"system_server"

"com.android.server.SystemServer",//对应的类名称

};

ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {

//将上述string参数转换为Argument参数

parsedArgs = new ZygoteConnection.Arguments(args);

ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);

ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

/* Request to fork the system server process */

//调用forkSystemServer 函数创建子进程

pid = Zygote.forkSystemServer(

parsedArgs.uid, parsedArgs.gid,

parsedArgs.gids,

parsedArgs.debugFlags,

null,

parsedArgs.permittedCapabilities,

parsedArgs.effectiveCapabilities);

} catch (IllegalArgumentException ex) {

throw new RuntimeException(ex);

}

/* For child process */

//子进程system_server 创建成功

if (pid == 0) {

//在子进程system_server 中调用handleSystemServerProcess

handleSystemServerProcess(parsedArgs);

}

return true;

}

两个重要步骤:1 调用forkSystemServer创建system_server子进程;2 子进程system_server中调用handleSystemServerProcess

1 调用forkSystemServer创建system_server子进程

其中forkSystemServer函数在Zygote.java文件中

public static int forkSystemServer(int uid, int gid, int[] gids,

int debugFlags, int[][] rlimits,

long permittedCapabilities, long effectiveCapabilities) {

preFork();

int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits,

permittedCapabilities,

effectiveCapabilities);

postFork();

return pid;

}

调用了本地函数nativeForkSystemServer,它在jni层对应的函数是dalvik/vm/native/dalvik_system_Zygote.cpp中的forkSystemServer函数

/* native public static int forkSystemServer(int uid, int gid,

*     int[] gids, int debugFlags, long permittedCapabilities,

*     long effectiveCapabilities);

*/

static void Dalvik_dalvik_system_Zygote_forkSystemServer(

const u4* args, JValue* pResult)

{

pid_t pid;

// 1.调用forkAndSpecializeCommon 创建进程

pid = forkAndSpecializeCommon(args, true);

/* The zygote process checks whether the child process has died or not. */

if (pid > 0) {

int status;

//在虚拟机中记录所创建进程system_server的进程id

gDvm.systemServerPid = pid;

// 2. 检查system_server进程是否异常,如果system_server进程异常退出,则zygote自己自杀。

//又因为在init中zygote配置onrestart,所以init会重启system_server进程

if (waitpid(pid, &status, WNOHANG) == pid) {

LOGE("System server process %d has died. Restarting Zygote!", pid);

kill(getpid(), SIGKILL);

}

}

RETURN_INT(pid);

}

system_server进程非常重要,如果启动失败导致zygote重启,上述功能主要有两个部分:1.调用forkAndSpecializeCommon创建system_server进程;2.监控system_server进程

先看创建system_server进程

1.调用forkAndSpecializeCommon创建system_server进程

/*

* Utility routine to fork zygote and specialize the child process.

*/

static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)

{

//...初始化启动参数

//设置信号处理函数

setSignalHandler();

//创建子进程

pid = fork();

if (pid == 0) {

int err;

/* The child process */

//..子进程处理操作

unsetSignalHandler();

} else if (pid > 0) {

//父进程中操作

}

return pid;

}

其中在创建子进程之前 调用setSignalHandler()设置信号处理函数

static void setSignalHandler()

{

int err;

struct sigaction sa;

memset(&sa, 0, sizeof(sa));

sa.sa_handler = sigchldHandler;

//注册信号处理函数,处理SIGCHLD 信号,该信号是子进程退出信号,对应的处理函数是sigchldHandler

err = sigaction (SIGCHLD, &sa, NULL);

}

那么加入收到自己进程退出信号SIGCHLD,调用sigchldHandler 函数来处理SIGCHLD

/*

* This signal handler is for zygote mode, since the zygote

* must reap its children

*/

static void sigchldHandler(int s)

{

pid_t pid;

int status;

while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {

if (WIFEXITED(status)) {

/*

* If the just-crashed process is the system_server, bring down zygote

* so that it is restarted by init and system server will be restarted

* from there.

*/

//如果退出的进程是system_server,则杀死zygote,让init重启zygote

if (pid == gDvm.systemServerPid) {

LOG(LOG_INFO, ZYGOTE_LOG_TAG,

"Exit zygote because system server (%d) has terminated",

(int) pid);

kill(getpid(), SIGKILL);

}

}

if (pid < 0) {

LOG(LOG_WARN, ZYGOTE_LOG_TAG,

"Zygote SIGCHLD error in waitpid: %s",strerror(errno));

}

}

可以看出子进程system_server是非常重要的,如果创建过程中出现了错误,直接导致zygote的重启,那么system_server在创建成功之后做了什么?

2 子进程system_server中调用handleSystemServerProcess

private static void handleSystemServerProcess(

ZygoteConnection.Arguments parsedArgs)

throws ZygoteInit.MethodAndArgsCaller {

//关闭从zygote中继承的socket

closeServerSocket();

// set umask to 0077 so new files and directories will default to owner-only permissions.

FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);

if (parsedArgs.niceName != null) {

Process.setArgV0(parsedArgs.niceName);

}

if (parsedArgs.invokeWith != null) {

WrapperInit.execApplication(parsedArgs.invokeWith,

parsedArgs.niceName, parsedArgs.targetSdkVersion,

null, parsedArgs.remainingArgs);

} else {

/*

* Pass the remaining arguments to SystemServer.

*/

//执行这个函数

RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);

}

/* should never reach here */

}

先进行一些清理和初始化工作,然后调用RuntimeInit.zygoteInit:

public static final void zygoteInit(int targetSdkVersion, String[] argv)

throws ZygoteInit.MethodAndArgsCaller {

redirectLogStreams();

commonInit();

zygoteInitNative();

applicationInit(targetSdkVersion, argv);

}

zygoteInit封装了四个方法

1.redirectLogStreams来重定向IO

/**

* Redirect System.out and System.err to the Android log.

*/

public static void redirectLogStreams() {

System.out.close();

System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));

System.err.close();

System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));

}

这段代码句式将java中的system.out和system.err重定向到android日志文件系统中

2.commonInit初始化通过操作

private static final void commonInit() {

/* set default handler; this applies to all threads in the VM */

Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());

TimezoneGetter.setInstance(new TimezoneGetter() {

@Override

public String getId() {

return SystemProperties.get("persist.sys.timezone");

}

});

TimeZone.setDefault(null);

new AndroidConfig();

//设置http连接

String userAgent = getDefaultUserAgent();

System.setProperty("http.agent", userAgent);

NetworkManagementSocketTagger.install();

//模拟器上的trace调试

String trace = SystemProperties.get("ro.kernel.android.tracing");

if (trace.equals("1")) {

Slog.i(TAG, "NOTE: emulator trace profiling enabled");

Debug.enableEmulatorTraceOutput();

}

initialized = true;

}

3.zygoteInitNative开始binder通信

public static final native void zygoteInitNative();

这是一个本地方法,对应的native函数在AndroidRuntime.cpp文件的com_android_internal_os_RuntimeInit_zygoteInit方法

static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)

{

gCurRuntime->onZygoteInit();

}

调用了AndroidRuntime中的onZygoteInit方法,该方法是一个虚函数,调用的是子类AppRuntime的onZygoteInit方法

virtual void onZygoteInit()

{

sp<ProcessState> proc = ProcessState::self();

proc->startThreadPool();

}

开始system_server的binder通信,后面介绍binder内容(非常重要)

4.applicationInit

private static void applicationInit(int targetSdkVersion, String[] argv)

throws ZygoteInit.MethodAndArgsCaller {

//设置runtime参数

VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);

VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

final Arguments args;

try {

args = new Arguments(argv);

} catch (IllegalArgumentException ex) {

return;

}

// Remaining arguments are passed to the start class‘s static main

invokeStaticMain(args.startClass, args.startArgs);

}

直接调用invokeStaticMain函数:

private static void invokeStaticMain(String className, String[] argv)

throws ZygoteInit.MethodAndArgsCaller {

Class<?> cl;

try {

//利用java反射机制加载类SystemServer

cl = Class.forName(className);

} catch (ClassNotFoundException ex) {

throw new RuntimeException(

"Missing class when invoking static main " + className,

ex);

}

//得到该类的main函数

Method m;

try {

m = cl.getMethod("main", new Class[] { String[].class });

} catch (NoSuchMethodException ex) {

throw new RuntimeException(

"Missing static main on " + className, ex);

} catch (SecurityException ex) {

throw new RuntimeException(

"Problem getting static main on " + className, ex);

}

//判断该main函数是否是static和public的

int modifiers = m.getModifiers();

if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {

throw new RuntimeException(

"Main method is not public and static on " + className);

}

//抛异常 ZygoteInit.MethodAndArgsCaller

throw new ZygoteInit.MethodAndArgsCaller(m, argv);

}

可以看出在最后抛了一个异常 ZygoteInit.MethodAndArgsCaller,那么肯定有处理异常的。

catch (MethodAndArgsCaller caller) {

// 5 执行MethodAndArgsCaller的run方法

caller.run();

}

4.3.4 处理异常MethodAndArgsCaller

可以看出异常处理方法就是执行该异常的run方法。我们先看MethodAndArgsCaller类,它是ZygoteInit.java的一个内部类

public static class MethodAndArgsCaller extends Exception

implements Runnable {

/** method to call */

private final Method mMethod;

/** argument array */

private final String[] mArgs;

public MethodAndArgsCaller(Method method, String[] args) {

mMethod = method;

mArgs = args;

}

public void run() {

try {

//利用java反射机制执行该方法

mMethod.invoke(null, new Object[] { mArgs });

} catch (IllegalAccessException ex) {

throw new RuntimeException(ex);

} catch (InvocationTargetException ex) {

...

}

}

}

就是执行构造时传入的方法,我们传入的是SystemServer的main方法,那么我们SystemServer的main方法做了什么?

public static void main(String[] args) {

// .....

// Mmmmmm... more memory! 这个注释有点卖萌 !!!

//1.更、更、更、更、更...多的内存

dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();

// The system server has to run all of the time, so it needs to be

// as efficient as possible with its memory usage.

VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

2.加载android_servers 库

System.loadLibrary("android_servers");

//3init1

init1(args);

}

三个工作:1.卖萌要内存;2.加载android_servers库;3.执行init1。其中前两个好理解,关键是init1函数

native public static void init1(String[] args);

1.init1 启动native system service

这是一个本地方法,对应的native方法在System_init.cpp中的system_init方法:

extern "C" status_t system_init()

{

//初始化binder通信

sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();

sp<GrimReaper> grim = new GrimReaper();

sm->asBinder()->linkToDeath(grim, grim.get(), 0);

char propBuf[PROPERTY_VALUE_MAX];

//读取属性值

property_get("system_init.startsurfaceflinger", propBuf, "1");

if (strcmp(propBuf, "1") == 0) {

//启动SurfaceFlinger

SurfaceFlinger::instantiate();

}

property_get("system_init.startsensorservice", propBuf, "1");

if (strcmp(propBuf, "1") == 0) {

// Start the sensor service

//启动SensorService

SensorService::instantiate();

}

AndroidRuntime* runtime = AndroidRuntime::getRuntime();

JNIEnv* env = runtime->getJNIEnv();

if (env == NULL) {

return UNKNOWN_ERROR;

}

//找到类com/android/server/SystemServer

jclass clazz = env->FindClass("com/android/server/SystemServer");

if (clazz == NULL) {

return UNKNOWN_ERROR;

}

//找到SystemServer 的init2函数

jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");

if (methodId == NULL) {

return UNKNOWN_ERROR;

}

//调用SystemServer 的init2函数

env->CallStaticVoidMethod(clazz, methodId);

//启动binder通信

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

return NO_ERROR;

}

主要工作1.读取配置文件判断是否启动SurfaceFlinger和SensorService;2调用SystemServer 的init2函数 ;3启动binder通信

这里只看init2函数调用

2.init2 启动java system service

init2函数:

public static final void init2() {

Thread thr = new ServerThread();

thr.setName("android.server.ServerThread");

thr.start();

}

启动一个ServerThread线程

class ServerThread extends Thread {

private static final String TAG = "SystemServer";

private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";

private static final String ENCRYPTED_STATE = "1";

ContentResolver mContentResolver;

@Override

public void run() {

//消息循环

Looper.prepare();

...

// Critical services...

//开启核心服务

try {

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

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

power = new PowerManagerService();

ServiceManager.addService(Context.POWER_SERVICE, power);

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

context = ActivityManagerService.main(factoryTest);

Slog.i(TAG, "Telephony Registry");

ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));

pm = PackageManagerService.main(context,

factoryTest != SystemServer.FACTORY_TEST_OFF,

onlyCore);

boolean firstBoot = false;

ActivityManagerService.setSystemProcess();

mContentResolver = context.getContentResolver();

Configuration config = wm.computeNewConfiguration();

DisplayMetrics metrics = new DisplayMetrics();

WindowManager w = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);

w.getDefaultDisplay().getMetrics(metrics);

context.getResources().updateConfiguration(config, metrics);

power.systemReady();

try {

pm.systemReady();

} catch (Throwable e) {

reportWtf("making Package Manager Service ready", e);

}

// These are needed to propagate to the runnable below.

//AMS准备就绪

ActivityManagerService.self().systemReady(new Runnable() {

public void run() {

Slog.i(TAG, "Making services ready");

startSystemUi(contextF);

try {

if (batteryF != null) batteryF.systemReady();

} catch (Throwable e) {

reportWtf("making Battery Service ready", e);

}

......

}

});

// For debug builds, log event loop stalls to dropbox for analysis.

if (StrictMode.conditionallyEnableDebugLogging()) {

Slog.i(TAG, "Enabled StrictMode for system server main thread.");

}

Looper.loop();

Slog.d(TAG, "System ServerThread is exiting!");

}

}

ServerThread启动了大量的核心服务,因此这个过程就是开启java system service。

4.3.5 ZygoteInit最后一步:runSelectLoopMode

private static void runSelectLoopMode() throws MethodAndArgsCaller {

ArrayList<FileDescriptor> fds = new ArrayList();

ArrayList<ZygoteConnection> peers = new ArrayList();

FileDescriptor[] fdArray = new FileDescriptor[4];

fds.add(sServerSocket.getFileDescriptor());

peers.add(null);

int loopCount = GC_LOOP_COUNT;

while (true) {//无线循环

int index;

if (loopCount <= 0) {

gc();

loopCount = GC_LOOP_COUNT;

} else {

loopCount--;

}

try {

fdArray = fds.toArray(fdArray);

index = selectReadable(fdArray);

} catch (IOException ex) {

throw new RuntimeException("Error in select()", ex);

}

if (index < 0) {

throw new RuntimeException("Error in select()");

} else if (index == 0) {//如果有客户端连接

//接受请求

ZygoteConnection newPeer = acceptCommandPeer();

peers.add(newPeer);

fds.add(newPeer.getFileDesciptor());

} else {

boolean done;

//执行runOnce

done = peers.get(index).runOnce();

if (done) {

peers.remove(index);

fds.remove(index);

}

}

}

}

runSelectLoopMode等待来自客户的消息,这里以Activiy为例来讲解zygote是如何分裂的

4.4 Zygote分裂

4.4.1 AMS发送请求

AMS是又systemserver创建的,如果有一个Activity要启动,而这个Activity所依附的进程还没有启动,那么流程是怎样的 ?

直接看AMS中的startProcessLocked 方法:

private final void startProcessLocked(ProcessRecord app,

String hostingType, String hostingNameStr) {

...

if ("1".equals(SystemProperties.get("debug.checkjni"))) {

debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;

}

if ("1".equals(SystemProperties.get("debug.jni.logging"))) {

debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;

}

if ("1".equals(SystemProperties.get("debug.assert"))) {

debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;

}

//调用Process.start

Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",

app.processName, uid, uid, gids, debugFlags,

app.info.targetSdkVersion, null);

}

直接看frameworks/base/core/java/android/os/Process.java中的start方法

public static final ProcessStartResult start(final String processClass,

final String niceName,

int uid, int gid, int[] gids,

int debugFlags, int targetSdkVersion,

String[] zygoteArgs) {

try {

//调用startViaZygote

return startViaZygote(processClass, niceName, uid, gid, gids,

debugFlags, targetSdkVersion, zygoteArgs);

} catch (ZygoteStartFailedEx ex) {

Log.e(LOG_TAG,

"Starting VM process through Zygote failed");

throw new RuntimeException(

"Starting VM process through Zygote failed", ex);

}

}

继续调用startViaZygote:

private static ProcessStartResult startViaZygote(final String processClass,

final String niceName,

final int uid, final int gid,

final int[] gids,

int debugFlags, int targetSdkVersion,

String[] extraArgs)

throws ZygoteStartFailedEx {

synchronized(Process.class) {

ArrayList<String> argsForZygote = new ArrayList<String>();

// --runtime-init, --setuid=, --setgid=,

// and --setgroups= must go first

argsForZygote.add("--runtime-init");

argsForZygote.add("--setuid=" + uid);

argsForZygote.add("--setgid=" + gid);

argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

//TODO optionally enable debuger

//argsForZygote.add("--enable-debugger");

// --setgroups is a comma-separated list

...

return zygoteSendArgsAndGetResult(argsForZygote);

}

}

调用zygoteSendArgsAndGetResult函数

private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)

throws ZygoteStartFailedEx {

//与socket通信?确认一下

openZygoteSocketIfNeeded();

try {

//按照一定格式向socket中写入数据

sZygoteWriter.write(Integer.toString(args.size()));

sZygoteWriter.newLine();

int sz = args.size();

for (int i = 0; i < sz; i++) {

String arg = args.get(i);

if (arg.indexOf(‘\n‘) >= 0) {

throw new ZygoteStartFailedEx(

"embedded newlines not allowed");

}

sZygoteWriter.write(arg);

sZygoteWriter.newLine();

}

sZygoteWriter.flush();

// Should there be a timeout on this?

ProcessStartResult result = new ProcessStartResult();

result.pid = sZygoteInputStream.readInt();

if (result.pid < 0) {

throw new ZygoteStartFailedEx("fork() failed");

}

result.usingWrapper = sZygoteInputStream.readBoolean();

return result;

} catch (IOException ex) {

...

}

}

一开始调用了openZygoteSocketIfNeeded,它的作用是什么?

/**

* Tries to open socket to Zygote process if not already open. If

* already open, does nothing.  May block and retry.

*/

private static void openZygoteSocketIfNeeded()

throws ZygoteStartFailedEx {

int retryCount;

if (sPreviousZygoteOpenFailed) {

retryCount = 0;

} else {

retryCount = 10;

}

for (int retry = 0

; (sZygoteSocket == null) && (retry < (retryCount + 1))

; retry++ ) {

try {

//创建socket

sZygoteSocket = new LocalSocket();

// 连接zygote的socket

sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,

LocalSocketAddress.Namespace.RESERVED));

sZygoteInputStream

= new DataInputStream(sZygoteSocket.getInputStream());

sZygoteWriter =

new BufferedWriter(

new OutputStreamWriter(

sZygoteSocket.getOutputStream()),

256);

Log.i("Zygote", "Process: zygote socket opened");

sPreviousZygoteOpenFailed = false;

break;

} catch (IOException ex) {

...

}

}

}

zygote等待的客户端连接就是AMS,AMS将请求发送给zygote的socket。而在runSelectLoopMode中,接受到客户端连接之后,执行ZygoteConnection的runOnce方法

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

String args[];

Arguments parsedArgs = null;

FileDescriptor[] descriptors;

try {

//读取参数

args = readArgumentList();

descriptors = mSocket.getAncillaryFileDescriptors();

} catch (IOException ex) {

Log.w(TAG, "IOException on command socket " + ex.getMessage());

closeSocket();

return true;

}

....

try {

parsedArgs = new Arguments(args);

//又创建一个新进程

pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,

parsedArgs.gids, parsedArgs.debugFlags, rlimits);

} catch (IOException ex) {

}   ....

try {

if (pid == 0) {

// in child

//处理子进程

handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

return true;

} else {

...

return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);

}

}

}

handleChildProc函数

private void handleChildProc(Arguments parsedArgs,

FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)

throws ZygoteInit.MethodAndArgsCaller {

//.....

if (parsedArgs.runtimeInit) {

if (parsedArgs.invokeWith != null) {

WrapperInit.execApplication(parsedArgs.invokeWith,

parsedArgs.niceName, parsedArgs.targetSdkVersion,

pipeFd, parsedArgs.remainingArgs);

} else {

//又开始执行zygoteInit 函数

RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,

parsedArgs.remainingArgs);

}

} else {

String className;

try {

className = parsedArgs.remainingArgs[0];

} catch (ArrayIndexOutOfBoundsException ex) {

logAndPrintError(newStderr,

"Missing required class name argument", null);

return;

}

}

}

又开始执行zygoteInit函数,redirectLogStreams,commonInit,zygoteInitNative,applicationInit四个阶段,最终执行invokeStaticMain启动指定类的main函数,这里是android.app.ActivityThread的main方法。

时间: 2024-10-07 21:11:15

第四章 Android启动过程的上层实现的相关文章

第三章 Android 启动过程的底层实现

转载请标明出处: http://blog.csdn.net/yujun411522/article/details/46367787 本文出自:[yujun411522的博客] 3.1 android正常模式启动流程 主要流程如下: 1.系统加电,执行bootloader,bootloader会将内核加载到内存中. 2.内核加载到内存之后首先进入内核引导阶段,最后调用start_kernel进入内核启动,start_kernel最终会启动init程序 3.init程序负责解析init.rc文件并

第四章 Android开发三大基石—Activity、Service和Handler(1)

第四章 Android开发三大基石-Activity.Service和Handler 学习Android开发,首先就不得不学习Activity和Service这两个组件.Activity是有界面的程序,几乎承载着用户对应用程序的所有操作.而Service是没有界面的程序,它是所谓的服务,也叫后台程序.掌握好它们,是我们学习Android开发必不可少的环节.Handler是Android开发中最常用的消息机制,几乎所有应用程序都会使用Handler传递消息.可以说,想要学习Android应用开发,

Android启动过程深入解析

Android启动过程深入解析 2014/06/20 分享到:7 本文由 伯乐在线 - 云海之巅 翻译.未经许可,禁止转载!英文出处:kpbird.欢迎加入翻译小组. 当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么样的? 什么是Linux内核? 桌面系统linux内核与Android系统linux内核有什么区别? 什么是引导装载程序? 什么是Zygote? 什么是X86以及ARM linux? 什么是init.rc? 什么是系统服务? 当我们想到Android启

【ALearning】第四章 Android Layout组件布局(二)

前面我们分别介绍和学习了LinearLayout(线性布局).FrameLayout(单帧布局)和AbsoluteLayout(绝对布局).这次我们要进行RelativeLayout(相对布局)和TableLayout(表格布局)的学习.这部分是很重要的知识点.RelativeLayout是开发过程中强烈建议使用的,而TableLayout是满足一些特定需求时(常见表格显示,但不局限于此)需要使用. [博客专栏:http://blog.csdn.net/column/details/alearn

Android启动过程

Android启动过程 1.  加载Linux内核 2. Android init进程对各种设备进行初始化,运行Android Framework所需用的各种Daemon(后台进程/守护进程),Context Manager,MediaServer,Zygote等 以下是init进程执行的Daemon进程: USB Daemon(usbd): 管理USB连接 Android Debug Bridge Daemon(adbd): Android  Debug Bridge连接管理 Debugger

Android学习笔记—第四章 Android开发组件2

第四章 Android开发组件2 列表类组件 (1)ListView组件:以垂直列表的形式列出需要显示的列表项 相关属性: a. android:divider  用于为列表视图设置分隔条,可以用颜色或者图片资源 b. android:dividerHeight  设置分隔条的高度 c. android:entries  通过数组资源为ListView指定列表项 d. android:footerDividersEnabled  设置是否在footerView之前绘制分隔条,默认为true. e

软件工程基础图式(第四章 系统设计-面向过程的系统设计)

软件工程基础图式(第四章 系统设计-面向过程的系统设计) 1.结构化设计方法 2.在系统结构图中的模块 3.变换型系统结构图 4.事务型系统结构图 5.变换分析 例子1:将下图的DFD/数据流图转换为软件/控制结构图(有误,看模式) 例子2:将下列数据流图转换为控制结构图 变换分析注意事项 ① 在选择模块设计的次序时,必须对一个模块的 全部直接下 属模块都设 计完成之后, 才能转向另 一个模块的 下层模块的 设计. ② 在设计下层模块时,应考虑模块的耦合和内聚问题,以提高初始结构图的质量. ③

Android 启动过程的底层实现

转载请标明出处: http://blog.csdn.net/yujun411522/article/details/46367787 本文出自:[yujun411522的博客] 3.1 android正常模式启动流程 主要流程例如以下: 1.系统加电.运行bootloader,bootloader会将内核载入到内存中. 2.内核载入到内存之后首先进入内核引导阶段,最后调用start_kernel进入内核启动.start_kernel终于会启动init程序 3.init程序负责解析init.rc文

Android启动过程——init,Zygote,SystemServer

一.Android设备启动经历的三个阶段:Boot Loader:Linux Kernel.Android系统服务:每一个阶段都有自己的启动画面. 1.Android中第一个被启动的进程--init,init进程的PID为1,其它的服务都由其进行创建.它是通过解析init.rc脚本来构建出系统的初始执行状态的.init进程是在系统启动启动过程中启动的. 2.init.rc语法规则: 1)Actions动作 一个Action实际上就是对应某个事件的过程. 以下给出boot事件的脚本 /* \sys