android APK应用安装过程以及默认安装路径_第1页
android APK应用安装过程以及默认安装路径_第2页
android APK应用安装过程以及默认安装路径_第3页
android APK应用安装过程以及默认安装路径_第4页
android APK应用安装过程以及默认安装路径_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、android APK应用安装过程以及默认安装路径 分类: Android一:安装过程APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。Android应用安装有如下四种方式1.        系统应用安装开机时完成,没有安装界面2.        网络下载应用安装通过market应用完成,没有安装界面3.        ADB工具安装没有安装界面。4.   &#

2、160;    第三方应用安装通过SD卡里的APK文件安装,有安装界面,由packageinstaller.apk应用处理安装及卸载过程的界面。应用安装的流程及路径 应用安装涉及到如下几个目录:system/app  系统自带的应用程序,无法删除 data/app 用户程序安装的目录,有删除权限。安装时把apk文件复制到此目录 data/data 存放应用程序的数据 Data/dalvik-cache 将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik

3、虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)        安装过程:复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录。       卸载过程:删除安装过程中在上述三个目录下创建的文件及目录。 一、系统应用安装: PackageManagerService处理各种应用的安装,卸载,管理等工作,开机时由systemServer启动此服务(源文件

4、路径:androidframeworksbaseservicesjavacomandroidserverPackageManagerService.java)PackageManagerService服务启动的流程:1. 首先扫描安装“systemframework”目录下的jar包1. scanDirLI(mFrameworkDir,PackageParser.PARSE_IS_SYSTEM,                    scanMode | SCAN_NO_DEX);2.第二步扫描

5、安装“systemapp”目录下的各个系统应用scanDirLI(mSystemAppDir,PackageParser.PARSE_IS_SYSTEM, scanMode);3.第三步扫描“dataapp”目录,即用户安装的第三方应用scanDirLI(mAppInstallDir, 0, scanMode);4.第四步扫描" dataapp-private"目录,即安装DRM保护的APK文件(目前没有遇到过此类的应用)。scanDirLI(mDrmAppPrivateInstallDir,0, scanMode | SCAN_FORWARD_LOCKED);安装应用的过

6、程1.scanDirLI(Filedir, int flags, int scanMode) 遍历安装指定目录下的文件2.scanPackageLI(FilescanFile,            File destCodeFile, FiledestResourceFile, int parseFlags,            int scanMode)                安装p

7、ackage文件3.scanPackageLI(        File scanFile, File destCodeFile, FiledestResourceFile,        PackageParser.Package pkg, intparseFlags, int scanMode)通过解析安装包parsePackage获取到安装包的信息结构4.mInstaller.install(pkgName,pkg.applicationInfo.uid,       

8、       pkg.applicationInfo.uid);   实现文件复制的安装过程(源文件路径:frameworksbasecmdsinstalldinstalld.install)二、从market上下载应用: Google Market应用需要使用gmail账户登录才可以使用,选择某一应用后,开始下载安装包,此过程中,在手机的信号区有进度条提示,下载完成后,会自动调用Packagemanager的接口安装,调用接口如下:public voidinstallPackage(final Uri packageURI, final IP

9、ackageInstallObserver observer,final int flags)final Uri packageURI:文件下载完成后保存的路径final IPackageInstallObserver observer:处理返回的安装结果final int flags:安装的参数,从market上下载的应用,安装参数为-r (replace)installPackage接口函数的安装过程:1.public voidinstallPackage(            final Uri packageURI, fin

10、al IPackageInstallObserverobserver, final int flags,            final String installerPackageName)final StringinstallerPackageName:安装完成后此名称保存在settings里,一般为null,不是关键参数2.FiletmpPackageFile = copyTempInstallFile(packageURI, res);把apk文件复制到临时目录下的临时文件3.private voidinstallPack

11、ageLI(Uri pPackageURI,            int pFlags, boolean newInstall,String installerPackageName,           File tmpPackageFile, PackageInstalledInfo res)解析临时文件,获取应用包名pkgName = PackageParser.parsePackageName(          &

12、#160;        tmpPackageFile.getAbsolutePath(), 0);4.判断如果带有参数INSTALL_REPLACE_EXISTING,则调用replacePackageLI(pkgName,                        tmpPackageFile,                   

13、;     destFilePath,destPackageFile, destResourceFile,                        pkg, forwardLocked,newInstall, installerPackageName,                        res)5.如果没有,则调用ins

14、tallNewPackageLI(pkgName,                        tmpPackageFile,                        destFilePath,destPackageFile, destResourceFile,            

15、60;           pkg,forwardLocked, newInstall, installerPackageName,                        res);6.privatePackageParser.Package scanPackageLI(        File scanFile, File destCodeFile, FiledestResou

16、rceFile,        PackageParser.Package pkg, intparseFlags, int scanMode)scanPackageLI以后的流程,与开机时的应用安装流程相同。三、从ADB工具安装 Android Debug Bridge (adb) 是SDK自带的管理设备的工具,通过ADB命令行的方式也可以为手机或模拟器安装应用,其入口函数源文件为pm.java(源文件路径:androidframeworksbasecmdspmsrccomandroidcommandspmpm.java)ADB命令行的形式为a

17、db install <path_to_apk> ,还可以带安装参数如:"-l""-r" "-i" "-t"函数runInstall()中判断参数"-l"INSTALL_FORWARD_LOCK "-r"INSTALL_REPLACE_EXISTING "-i" installerPackageName"-t"INSTALL_ALLOW_TEST我们常用的参数为-r,表示覆盖安装手机上已安装的同名应用。从

18、market上下载的应用,也是直接传入这个参数安装的。runInstall与market调用同样的接口完成应用安装。public voidinstallPackage(.Uri packageURI,android.content.pm.IPackageInstallObserver observer, int flags,java.lang.String installerPackageName)四、第三方应用安装通过SD卡里的APK文件安装 把APK安装包保存在SD卡中,从手机里访问SD卡中的APK安装包,点击就可以启动安装界面,系统应用Packageinstaller.apk处

19、理这种方式下的安装及卸载界面流程,如下图:PackageInstallerActivity负责解析包,判断是否是可用的Apk文件创建临时安装文件/data/data/com.android.packageinstaller/files/ApiDemos.apk并启动安装确认界面startInstallConfirm,列出解析得到的该应用基本信息。如果手机上已安装有同名应用,则需要用户确认是否要替换安装。确认安装后,启动InstallAppProgress,调用安装接口完成安装。pm.installPackage(mPackageURI,observer, installFlags);其它:&#

20、160;1. PackageManagerService.java的内部类AppDirObserver实现了监听app目录的功能:当把某个APK拖到app目录下时,可以直接调用scanPackageLI完成安装。2.手机数据区目录“data/system/packages.xml”文件中,包含了手机上所有已安装应用的基本信息,如安装路径,申请的permission等信息。二:更改默认安装路径    如果你是一个apk应用开发者,没用android系统全套代码,你只想更改你的APK的默认安装路径的话,可以按下面方法来更改:在AndroidManifest.xml文件Manif

21、est标签中添加android:installLocation属性android:installLocation这个属性设置的是默认安装位置, 共有三个有效值,auto、internalOnly、preferExternal对应表auto 表示自动,由系统决定安装位置,如果系统手机内存足够,默认安装在手机内存里,如果手机内在不够,则会安装在T卡内internalOnly 安装在手机内存preferExternal 安装在外部存储中ConstantValueDescriptionauto0Let the system decide install locationinternalOnly1Exp

22、licitly request to be installed on internal phone storage onlypreferExternal2Perfer to be installed on SD card, There is no guarantee that the system will honor this request. The application might end up being installed on internal storage if external media is unavailable or too full <manife

23、st xmlns:android=" package="com.ray" android:installLocation="auto" android:versionCode="1" android:versionName="1.0">如果你是一个手机方案开发者,能改framework层的代码,你希望下载到手机里的APK都默认优先安装到T卡的话,可以按下面方法更改:在PackageParser.java文件里,将private static final int PARSE_DEFAULT_INSTA

24、LL_LOCATION  这个PARSE_DEFAULT_INSTALL_LOCATION值,改为PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL,就可以了.默认下载就会下到T卡里,T卡不存在或者满了时,才会下到手机内部. 或者如果在应用的AndroidManifest.xml里,指定了installLocation属性为手机内部存储的话,是会存在手机内部的.没指这定的话,PARSE_DEFAULT_INSTALL_LOCATION这个值指定什么,就下到哪里安装在T卡里的应用,有几个缺点:1:因为android装载T卡是在系统启动完成后,才开始

25、装载的.所以如果应用装在T卡里的话,那么它是收不到开机启动完成的BOOT_COMPLETED这个广播的2:如果T卡损坏或者T卡拨出来了,那么装在T卡里的应用是启动不了的.系统应用安装的详细过程,老罗有篇文章写得很透彻,这里引用下:Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息,完成应用程序的安装过程,本文将详细分析这个过程。        应用程序管理服务Pack

26、ageManagerService安装应用程序的过程,其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件Activity、Service、Broadcast Receiver和Content Provider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。        应用程序管理服务PackageManagerService是系统启动的时候由SystemServer组件启动的,启后

27、它就会执行应用程序安装的过程,因此,本文将从SystemServer启动PackageManagerService服务的过程开始分析系统中的应用程序安装的过程。        应用程序管理服务PackageManagerService从启动到安装应用程序的过程如下图所示:        下面我们具体分析每一个步骤。        Step 1. SystemServer.main        这

28、个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:java view plaincopy1. public class SystemServer  2.   3.     .  4.   5.     native public static void init1(S

29、tring args);  6.   7.     .  8.   9.     public static void main(String args)   10.         .  11.   12.   

30、60;     init1(args);  13.   14.         .  15.       16.   17.     .  18.           SystemServer组件是由

31、Zygote进程负责启动的,启动的时候就会调用它的main函数,这个函数主要调用了JNI方法init1来做一些系统初始化的工作。        Step 2. SystemServer.init1        这个函数是一个JNI方法,实现在 frameworks/base/services/jni/com_android_server_SystemServer.cpp文件中:cpp view plaincopy1. namespace android 

32、  2.   3. extern "C" int system_init();  4.   5. static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)  6.   7.     system_init();  8.  

33、; 9.   10. /* 11.  * JNI registration. 12.  */  13. static JNINativeMethod gMethods =   14.     /* name, signature, funcPtr */  15.      &qu

34、ot;init1", "(Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 ,  16. ;  17.   18. int register_android_server_SystemServer(JNIEnv* env)  19.   20.     return jniReg

35、isterNativeMethods(env, "com/android/server/SystemServer",  21.             gMethods, NELEM(gMethods);  22.   23.   24. ; / namespace android    

36、      这个函数很简单,只是调用了system_init函数来进一步执行操作。        Step 3. libsystem_server.system_init        函数system_init实现在libsystem_server库中,源代码位于frameworks/base/cmds/system_server/library/system_init.cpp文件中:cpp view plaincopy1. extern

37、60;"C" status_t system_init()  2.   3.     LOGI("Entered system_init()");  4.   5.     sp<ProcessState> proc(ProcessState:self();  6.   7.   

38、60; sp<IServiceManager> sm = defaultServiceManager();  8.     LOGI("ServiceManager: %pn", sm.get();  9.   10.     sp<GrimReaper> grim = new GrimReaper(); 

39、; 11.     sm->asBinder()->linkToDeath(grim, grim.get(), 0);  12.   13.     char propBufPROPERTY_VALUE_MAX;  14.     property_get("system_init.startsurfaceflinger", propB

40、uf, "1");  15.     if (strcmp(propBuf, "1") = 0)   16.         / Start the SurfaceFlinger  17.         Su

41、rfaceFlinger:instantiate();  18.       19.   20.     / Start the sensor service  21.     SensorService:instantiate();  22.   23.     / 

42、On the simulator, audioflinger et al don't get started the  24.     / same way as on the device, and we need to start them here  25.   &

43、#160; if (!proc->supportsProcesses()   26.   27.         / Start the AudioFlinger  28.         AudioFlinger:instantiate();  29.   30. 

44、60;       / Start the media playback service  31.         MediaPlayerService:instantiate();  32.   33.         / Start t

45、he camera service  34.         CameraService:instantiate();  35.   36.         / Start the audio policy service  37.     

46、0;   AudioPolicyService:instantiate();  38.       39.   40.     / And now start the Android runtime.  We have to do this bit  41.  

47、0;  / of nastiness because the Android runtime initialization requires  42.     / some of the core system services to already be started.  43.    

48、; / All other servers should just start the Android runtime at  44.     / the beginning of their processes's main(), before calling  45.     

49、/ the init function.  46.     LOGI("System server: starting Android runtime.n");  47.   48.     AndroidRuntime* runtime = AndroidRuntime:getRuntime();  49. 

50、0; 50.     LOGI("System server: starting Android services.n");  51.     runtime->callStatic("com/android/server/SystemServer", "init2");  52.   53.    &

51、#160;/ If running in our own process, just go into the thread  54.     / pool.  Otherwise, call the initialization finished  55.     / func 

52、to let this process continue its initilization.  56.     if (proc->supportsProcesses()   57.         LOGI("System server: entering thread pool.n");

53、  58.         ProcessState:self()->startThreadPool();  59.         IPCThreadState:self()->joinThreadPool();  60.         LOGI("System 

54、server: exiting thread pool.n");  61.       62.   63.     return NO_ERROR;  64.           这个函数首先会初始化SurfaceFlinger、SensorService、AudioFlinger、MediaPlayerService

55、、CameraService和AudioPolicyService这几个服务,然后就通过系统全局唯一的AndroidRuntime实例变量runtime的callStatic来调用SystemServer的init2函数了。关于这个AndroidRuntime实例变量runtime的相关资料,可能参考前面一篇文章Android应用程序进程启动过程的源代码分析一文。        Step 4. AndroidRuntime.callStatic        这个函数定义在frameworks/

56、base/core/jni/AndroidRuntime.cpp文件中:cpp view plaincopy1. /* 2. * Call a static Java Programming Language function that takes no arguments and returns void. 3. */  4. status_t AndroidRuntime:callStatic

57、(const char* className, const char* methodName)  5.   6.     JNIEnv* env;  7.     jclass clazz;  8.     jmethodID methodId;  9.   10.  

58、   env = getJNIEnv();  11.     if (env = NULL)  12.         return UNKNOWN_ERROR;  13.   14.     clazz = findClass(env, 

59、className);  15.     if (clazz = NULL)   16.         LOGE("ERROR: could not find class '%s'n", className);  17.      

60、   return UNKNOWN_ERROR;  18.       19.     methodId = env->GetStaticMethodID(clazz, methodName, "()V");  20.     if (methodId = NULL) &#

61、160; 21.         LOGE("ERROR: could not find method %s.%sn", className, methodName);  22.         return UNKNOWN_ERROR;  23.    &#

62、160;  24.   25.     env->CallStaticVoidMethod(clazz, methodId);  26.   27.     return NO_ERROR;  28.           这个函数调用由参数className指定的java类的静态成员函数,这个静态成员函数是由参数metho

63、dName指定的。上面传进来的参数className的值为"com/android/server/SystemServer",而参数methodName的值为"init2",因此,接下来就会调用SystemServer类的init2函数了。        Step 5. SystemServer.init2        这个函数定义在frameworks/base/services/java/com/android/server/SystemS

64、erver.java文件中:java view plaincopy1. public class SystemServer  2.   3.     .  4.   5.     public static final void init2()   6.        

65、 Slog.i(TAG, "Entered the Android system server!");  7.         Thread thr = new ServerThread();  8.         thr.setName("android.serve

66、r.ServerThread");  9.         thr.start();  10.       11.           这个函数创建了一个ServerThread线程,PackageManagerService服务就是这个线程中启动的了。这里调用了ServerThread实例thr的start函数之后,下面就会执行这个实例

67、的run函数了。        Step 6. ServerThread.run        这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:java view plaincopy1. class ServerThread extends Thread   2.     

68、.  3.   4.     Override  5.     public void run()   6.         .  7.   8.         IPackageManager pm

69、 = null;  9.   10.         .  11.   12.         / Critical services.  13.         try   14. 

70、60;           .  15.   16.             Slog.i(TAG, "Package Manager");  17.           

71、;  pm = PackageManagerService.main(context,  18.                         factoryTest != SystemServer.FACTORY_TEST_OFF);  19.  

72、; 20.             .  21.          catch (RuntimeException e)   22.             Slog.e("Sys

73、tem", "Failure starting core service", e);  23.           24.   25.         .  26.       27.   28. &

74、#160;   .  29.           这个函数除了启动PackageManagerService服务之外,还启动了其它很多的服务,例如在前面学习Activity和Service的几篇文章中经常看到的ActivityManagerService服务,有兴趣的读者可以自己研究一下。        Step 7. PackageManagerService.main     

75、60;  这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:cpp view plaincopy1. class PackageManagerService extends IPackageManager.Stub   2.     .  3.   4.     public&

76、#160;static final IPackageManager main(Context context, boolean factoryTest)   5.         PackageManagerService m = new PackageManagerService(context, factoryTest);  6.   

77、;      ServiceManager.addService("package", m);  7.         return m;  8.       9.   10.     .  11.    &#

78、160;      这个函数创建了一个PackageManagerService服务实例,然后把这个服务添加到ServiceManager中去,ServiceManager是Android系统Binder进程间通信机制的守护进程,负责管理系统中的Binder对象,具体可以参考浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路一文。        在创建这个PackageManagerService服务实例时,会在PackageManagerService类的构造函数

79、中开始执行安装应用程序的过程:java view plaincopy1. class PackageManagerService extends IPackageManager.Stub   2.     .  3.   4.     public PackageManagerService(Context context, boolean factoryTest)&

80、#160;  5.         .  6.   7.         synchronized (mInstallLock)   8.             synchronized (mPackages

81、)   9.                 .  10.   11.                 File dataDir = Environment.getDataDire

82、ctory();  12.                 mAppDataDir = new File(dataDir, "data");  13.                

83、0;mSecureAppDataDir = new File(dataDir, "secure/data");  14.                 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");  1

84、5.   16.                 .  17.   18.                 mFrameworkDir = new File(Environment.getR

85、ootDirectory(), "framework");  19.                 mDalvikCacheDir = new File(dataDir, "dalvik-cache");  20.   21.      

86、           .  22.   23.                 / Find base frameworks (resource packages without code).  24

87、.                 mFrameworkInstallObserver = new AppDirObserver(  25.                 mFrameworkDir.getPath(),

88、0;OBSERVER_EVENTS, true);  26.                 mFrameworkInstallObserver.startWatching();  27.                 scan

89、DirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM  28.                     | PackageParser.PARSE_IS_SYSTEM_DIR,  29.         

90、0;           scanMode | SCAN_NO_DEX, 0);  30.   31.                 / Collect all system packages.  

91、32.                 mSystemAppDir = new File(Environment.getRootDirectory(), "app");  33.                

92、 mSystemInstallObserver = new AppDirObserver(  34.                     mSystemAppDir.getPath(), OBSERVER_EVENTS, true);  35.     &

93、#160;           mSystemInstallObserver.startWatching();  36.                 scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM  37. 

94、60;                   | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);  38.   39.               &#

95、160; / Collect all vendor packages.  40.                 mVendorAppDir = new File("/vendor/app");  41.         

96、;        mVendorInstallObserver = new AppDirObserver(  42.                     mVendorAppDir.getPath(), OBSERVER_EVENTS, true

97、);  43.                 mVendorInstallObserver.startWatching();  44.                 scanDirLI(mVendorAppDir, Packa

98、geParser.PARSE_IS_SYSTEM  45.                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);  46.   47.   48.     

99、60;           mAppInstallObserver = new AppDirObserver(  49.                     mAppInstallDir.getPath(), OBSERVER

100、_EVENTS, false);  50.                 mAppInstallObserver.startWatching();  51.                 scanDirLI(mAppInsta

101、llDir, 0, scanMode, 0);  52.   53.                 mDrmAppInstallObserver = new AppDirObserver(  54.           

102、;          mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);  55.                 mDrmAppInstallObserver.startWatching();  56.           &#

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论