Android系統在啟動的過程中,會啟動一個應用程式管理服務PackageManagerService,這個服務負責掃描系統中特定的目錄,找到裡面的應用程式檔案,即以Apk為字尾的檔案,然後對這些檔案進解析,得到應用程式的相關資訊,完成應用程式的安裝過程,本文将詳細分析這個過程。
應用程式管理服務PackageManagerService安裝應用程式的過程,其實就是解析析應用程式配置檔案AndroidManifest.xml的過程,并從裡面得到得到應用程式的相關資訊,例如得到應用程式的元件Activity、Service、Broadcast Receiver和Content Provider等資訊,有了這些資訊後,通過ActivityManagerService這個服務,我們就可以在系統中正常地使用這些應用程式了。
應用程式管理服務PackageManagerService是系統啟動的時候由SystemServer元件啟動的,啟後它就會執行應用程式安裝的過程,是以,本文将從SystemServer啟動PackageManagerService服務的過程開始分析系統中的應用程式安裝的過程。
應用程式管理服務PackageManagerService從啟動到安裝應用程式的過程如下圖所示:
下面我們具體分析每一個步驟。
Step 1. SystemServer.main
這個函數定義在frameworks/base/services/java/com/android/server/SystemServer.java檔案中:
<b>[java]</b> view plaincopy
public class SystemServer
{
......
native public static void init1(String[] args);
public static void main(String[] args) {
......
init1(args);
}
}
SystemServer元件是由Zygote程序負責啟動的,啟動的時候就會調用它的main函數,這個函數主要調用了JNI方法init1來做一些系統初始化的工作。
Step 2. SystemServer.init1
這個函數是一個JNI方法,實作在 frameworks/base/services/jni/com_android_server_SystemServer.cpp檔案中:
<b>[cpp]</b> view plaincopy
namespace android {
extern "C" int system_init();
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
system_init();
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
};
int register_android_server_SystemServer(JNIEnv* env)
return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
gMethods, NELEM(gMethods));
}; // namespace android
這個函數很簡單,隻是調用了system_init函數來進一步執行操作。
Step 3. libsystem_server.system_init
函數system_init實作在libsystem_server庫中,源代碼位于frameworks/base/cmds/system_server/library/system_init.cpp檔案中:
extern "C" status_t system_init()
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
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) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
// Start the sensor service
SensorService::instantiate();
// On the simulator, audioflinger et al don't get started the
// same way as on the device, and we need to start them here
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();
// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
LOGI("System server: starting Android services.\n");
runtime->callStatic("com/android/server/SystemServer", "init2");
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
return NO_ERROR;
這個函數首先會初始化SurfaceFlinger、SensorService、AudioFlinger、MediaPlayerService、CameraService和AudioPolicyService這幾個服務,然後就通過系統全局唯一的AndroidRuntime執行個體變量runtime的callStatic來調用SystemServer的init2函數了。關于這個AndroidRuntime執行個體變量runtime的相關資料,可能參考前面一篇文章Android應用程式程序啟動過程的源代碼分析一文。 Step 4. AndroidRuntime.callStatic
這個函數定義在frameworks/base/core/jni/AndroidRuntime.cpp檔案中:
* Call a static Java Programming Language function that takes no arguments and returns void.
*/
status_t AndroidRuntime::callStatic(const char* className, const char* methodName)
JNIEnv* env;
jclass clazz;
jmethodID methodId;
env = getJNIEnv();
if (env == NULL)
return UNKNOWN_ERROR;
clazz = findClass(env, className);
if (clazz == NULL) {
LOGE("ERROR: could not find class '%s'\n", className);
methodId = env->GetStaticMethodID(clazz, methodName, "()V");
if (methodId == NULL) {
LOGE("ERROR: could not find method %s.%s\n", className, methodName);
env->CallStaticVoidMethod(clazz, methodId);
這個函數調用由參數className指定的java類的靜态成員函數,這個靜态成員函數是由參數methodName指定的。上面傳進來的參數className的值為"com/android/server/SystemServer",而參數methodName的值為"init2",是以,接下來就會調用SystemServer類的init2函數了。