Android 应用程序安装过程解析
在 Android 系统中,apk 安装文件是会被保存起来的,默认情况下,用户安装的 apk 首先会被拷贝到 /data/app 目录下。
/data/app 目录是用户有权限访问的目录,在安装 apk 的时候会自动选择该目录存放用户安装的文件,而系统出厂的 apk 文件则被放到了 /system 分区下, 包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,该分区只有 Root 权限的用户才能访问,这也就是为什么在没有 Root 手机之前,我们无法删除系统出厂的 app 的原因了。
为了加快 app 的启动速度,apk 在安装的时候,会首先将 app 的可执行文件(dex)拷贝到 /data/dalvik-cache 目录,缓存起来。
然后,在 / data/data / 目录下创建应用程序的数据目录(以应用的包名命名),存放应用的相关数据,如数据库、xml 文件、cache、二进制的 so 动态库等等。
Android 系统中,也有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何 apk 文件,都会更新这个文件。这个文件位于如下目录:
/data/system/packages.xml
系统在安装 apk 的过程中,会解析 apk 的 AndroidManifinest.xml 文件,提取出这个 apk 的重要信息写入到 packages.xml 文件中,这些信息包括:权限、应用包名、APK 的安装位置、版本、userID 等等。
由此,我们就知道了为啥一些应用市场和软件管理类的 app 能够很清楚地知道当前手机所安装的所有的 app,以及这些 app 的详细信息了。
另外一件事就是 Linux 的用户 Id 和用户组 Id,以便他可以获得合适的运行权限。
以上这些都是由 PackageServiceManager 完成的,下面我们会重点介绍 PackageServiceManager。
这些应用程序只是相当于在 PackageManagerService 服务注册好了,如果我们想要在 Android 桌面上看到这些应用程序,还需要有一个 Home 应用程序,负责从 PackageManagerService 服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在 Android 系统中,负责把系统中已经安装的应用程序在桌面中展现出来的 Home 应用程序就是 Launcher 了
Android 系统在启动的过程中,会启动一个应用程序管理服务 PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以 Apk 为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息。应用程序管理服务 PackageManagerService 安装应用程序的过程,其实就是解析析应用程序配置文件 AndroidManifest.xml 的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件 Activity、Service、Broadcast Receiver 和 Content Provider 等信息,有了这些信息后,通过 ActivityManagerService 这个服务,我们就可以在系统中正常地使用这些应用程序了。应用程序管理服务 PackageManagerService 是系统启动的时候由 SystemServer 组件启动的,启后它就会执行应用程序安装的过程,因此,本文将从 SystemServer 启动 PackageManagerService 服务的过程开始分析系统中的应用程序安装的过程。
这个函数定义在 frameworks/base/services/Java/com/android/server/SystemServer.java 文件中:
- public class SystemServer
- {
- ......
- native public static void init1(String[] args);
- ......
- public static void main(String[] args) {
- ......
- init1(args);
- ......
- }
- ......
- }
SystemServer 组件是由 Zygote 进程负责启动的,启动的时候就会调用它的 main 函数,这个函数主要调用了 JNI 方法 init1 来做一些系统初始化的工作。
这个函数是一个 JNI 方法,实现在 frameworks/base/services/jni/com_android_server_SystemServer.cpp 文件中:
- 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 函数来进一步执行操作。
函数 system_init 实现在 libsystem_server 库中,源代码位于 frameworks/base/cmds/system_server/library/system_init.cpp 文件中:
- extern "C" status_t system_init()
- {
- LOGI("Entered system_init()");
- sp proc(ProcessState::self());
- sp sm = defaultServiceManager();
- LOGI("ServiceManager: %p\n", sm.get());
- sp 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 应用程序进程启动过程的源代码分析一文。
这个函数定义在 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);
- return UNKNOWN_ERROR;
- }
- methodId = env->GetStaticMethodID(clazz, methodName, "()V");
- if (methodId == NULL) {
- LOGE("ERROR: could not find method %s.%s\n", className, methodName);
- return UNKNOWN_ERROR;
- }
- env->CallStaticVoidMethod(clazz, methodId);
- return NO_ERROR;
- }
这个函数调用由参数 className 指定的 java 类的静态成员函数,这个静态成员函数是由参数 methodName 指定的。上面传进来的参数 className 的值为 "com/android/server/SystemServer",而参数 methodName 的值为 "init2",因此,接下来就会调用 SystemServer 类的 init2 函数了。
这个函数定义在 frameworks/base/services/java/com/android/server/SystemServer.java 文件中:
- public class SystemServer
- {
- ......
- public static final void init2() {
- Slog.i(TAG, "Entered the Android system server!");
- Thread thr = new ServerThread();
- thr.setName("android.server.ServerThread");
- thr.start();
- }
- }
这个函数创建了一个 ServerThread 线程,PackageManagerService 服务就是这个线程中启动的了。这里调用了 ServerThread 实例 thr 的 start 函数之后,下面就会执行这个实例的 run 函数了。
这个函数定义在 frameworks/base/services/java/com/android/server/SystemServer.java 文件中:
- class ServerThread extends Thread {
- ......
- @Override
- public void run() {
- ......
- IPackageManager pm = null;
- ......
- // Critical services...
- try {
- ......
- Slog.i(TAG, "Package Manager");
- pm = PackageManagerService.main(context,
- factoryTest != SystemServer.FACTORY_TEST_OFF);
- ......
- } catch (RuntimeException e) {
- Slog.e("System", "Failure starting core service", e);
- }
- ......
- }
- ......
- }
这个函数除了启动 PackageManagerService 服务之外,还启动了其它很多的服务,例如在前面学习 Activity 和 Service 的几篇文章中经常看到的 ActivityManagerService 服务,有兴趣的读者可以自己研究一下。
这个函数定义在 frameworks/base/services/java/com/android/server/PackageManagerService.java 文件中:
- class PackageManagerService extends IPackageManager.Stub {
- ......
- public static final IPackageManager main(Context context, boolean factoryTest) {
- PackageManagerService m = new PackageManagerService(context, factoryTest);
- ServiceManager.addService("package", m);
- return m;
- }
- ......
- }
来源: http://www.bubuko.com/infodetail-1967084.html