Android应用程序安装过程源代码分…

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文件中:

view plain
  1. publicclassSystemServer
  2. {
  3. ......
  4. nativepublicstaticvoidinit1(String[]args);
  5. ......
  6. publicstaticvoidmain(String[]args){
  7. ......
  8. init1(args);
  9. ......
  10. }
  11. ......
  12. }
SystemServer组件是由Zygote进程负责启动的,启动的时候就会调用它的main函数,这个函数主要调用了JNI方法init1来做一些系统初始化的工作。

Step 2. SystemServer.init1

这个函数是一个JNI方法,实现在frameworks/base/services/jni/com_android_server_SystemServer.cpp文件中:

view plain
  1. namespaceandroid{
  2. extern"C"intsystem_init();
  3. staticvoidandroid_server_SystemServer_init1(JNIEnv*env,jobjectclazz)
  4. {
  5. system_init();
  6. }
  7. staticJNINativeMethodgMethods[]={
  8. {"init1","([Ljava/lang/String;)V",(void*)android_server_SystemServer_init1},
  9. };
  10. intregister_android_server_SystemServer(JNIEnv*env)
  11. {
  12. returnjniRegisterNativeMethods(env,"com/android/server/SystemServer",
  13. gMethods,NELEM(gMethods));
  14. }
  15. };//namespaceandroid
这个函数很简单,只是调用了system_init函数来进一步执行操作。

Step 3.libsystem_server.system_init

函数system_init实现在libsystem_server库中,源代码位于frameworks/base/cmds/system_server/library/system_init.cpp文件中:

view plain
  1. extern"C"status_tsystem_init()
  2. {
  3. LOGI("Enteredsystem_init()");
  4. sp<ProcessState>proc(ProcessState::self());
  5. sp<IServiceManager>sm=defaultServiceManager();
  6. LOGI("ServiceManager:%p\n",sm.get());
  7. sp<GrimReaper>grim=newGrimReaper();
  8. sm->asBinder()->linkToDeath(grim,grim.get(),0);
  9. charpropBuf[PROPERTY_VALUE_MAX];
  10. property_get("system_init.startsurfaceflinger",propBuf,"1");
  11. if(strcmp(propBuf,"1")==0){
  12. //StarttheSurfaceFlinger
  13. SurfaceFlinger::instantiate();
  14. }
  15. //Startthesensorservice
  16. SensorService::instantiate();
  17. //Onthesimulator,audioflingeretaldon'tgetstartedthe
  18. //samewayasonthedevice,andweneedtostartthemhere
  19. if(!proc->supportsProcesses()){
  20. //StarttheAudioFlinger
  21. AudioFlinger::instantiate();
  22. //Startthemediaplaybackservice
  23. MediaPlayerService::instantiate();
  24. //Startthecameraservice
  25. CameraService::instantiate();
  26. //Starttheaudiopolicyservice
  27. AudioPolicyService::instantiate();
  28. }
  29. //AndnowstarttheAndroidruntime.Wehavetodothisbit
  30. //ofnastinessbecausetheAndroidruntimeinitializationrequires
  31. //someofthecoresystemservicestoalreadybestarted.
  32. //AllotherserversshouldjuststarttheAndroidruntimeat
  33. //thebeginningoftheirprocesses'smain(),beforecalling
  34. //theinitfunction.
  35. LOGI("Systemserver:startingAndroidruntime.\n");
  36. AndroidRuntime*runtime=AndroidRuntime::getRuntime();
  37. LOGI("Systemserver:startingAndroidservices.\n");
  38. runtime->callStatic("com/android/server/SystemServer","init2");
  39. //Ifrunninginourownprocess,justgointothethread
  40. //pool.Otherwise,calltheinitializationfinished
  41. //functoletthisprocesscontinueitsinitilization.
  42. if(proc->supportsProcesses()){
  43. LOGI("Systemserver:enteringthreadpool.\n");
  44. ProcessState::self()->startThreadPool();
  45. IPCThreadState::self()->joinThreadPool();
  46. LOGI("Systemserver:exitingthreadpool.\n");
  47. }
  48. returnNO_ERROR;
  49. }
这个函数首先会初始化SurfaceFlinger、SensorService、AudioFlinger、MediaPlayerService、CameraService和AudioPolicyService这几个服务,然后就通过系统全局唯一的AndroidRuntime实例变量runtime的callStatic来调用SystemServer的init2函数了。关于这个AndroidRuntime实例变量runtime的相关资料,可能参考前面一篇文章Android应用程序进程启动过程的源代码分析一文。

Step 4. AndroidRuntime.callStatic

这个函数定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

view plain
  1. status_tAndroidRuntime::callStatic(constchar*className,constchar*methodName)
  2. {
  3. JNIEnv*env;
  4. jclassclazz;
  5. jmethodIDmethodId;
  6. env=getJNIEnv();
  7. if(env==NULL)
  8. returnUNKNOWN_ERROR;
  9. clazz=findClass(env,className);
  10. if(clazz==NULL){
  11. LOGE("ERROR:couldnotfindclass'%s'\n",className);
  12. returnUNKNOWN_ERROR;
  13. }
  14. methodId=env->GetStaticMethodID(clazz,methodName,"()V");
  15. if(methodId==NULL){
  16. LOGE("ERROR:couldnotfindmethod%s.%s\n",className,methodName);
  17. returnUNKNOWN_ERROR;
  18. }
  19. env->CallStaticVoidMethod(clazz,methodId);
  20. returnNO_ERROR;
  21. }
这个函数调用由参数className指定的java类的静态成员函数,这个静态成员函数是由参数methodName指定的。上面传进来的参数className的值为"com/android/server/SystemServer",而参数methodName的值为"init2",因此,接下来就会调用SystemServer类的init2函数了。

Step 5.SystemServer.init2

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:

view plain
  1. publicclassSystemServer
  2. {
  3. ......
  4. publicstaticfinalvoidinit2(){
  5. Slog.i(TAG,"EnteredtheAndroidsystemserver!");
  6. Threadthr=newServerThread();
  7. thr.setName("android.server.ServerThread");
  8. thr.start();
  9. }
  10. }
这个函数创建了一个ServerThread线程,PackageManagerService服务就是这个线程中启动的了。这里调用了ServerThread实例thr的start函数之后,下面就会执行这个实例的run函数了。

Step 6.ServerThread.run

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:

view plain
  1. classServerThreadextendsThread{
  2. ......
  3. @Override
  4. publicvoidrun(){
  5. ......
  6. IPackageManagerpm=null;
  7. ......
  8. //Criticalservices...
  9. try{
  10. ......
  11. Slog.i(TAG,"PackageManager");
  12. pm=PackageManagerService.main(context,
  13. factoryTest!=SystemServer.FACTORY_TEST_OFF);
  14. ......
  15. }catch(RuntimeExceptione){
  16. Slog.e("System","Failurestartingcoreservice",e);
  17. }
  18. ......
  19. }
  20. ......
  21. }
这个函数除了启动PackageManagerService服务之外,还启动了其它很多的服务,例如在前面学习Activity和Service的几篇文章中经常看到的ActivityManagerService服务,有兴趣的读者可以自己研究一下。

Step 7.PackageManagerService.main

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:

view plain
  1. classPackageManagerServiceextendsIPackageManager.Stub{
  2. ......
  3. publicstaticfinalIPackageManagermain(Contextcontext,booleanfactoryTest){
  4. PackageManagerServicem=newPackageManagerService(context,factoryTest);
  5. ServiceManager.addService("package",m);
  6. returnm;
  7. }
  8. ......
  9. }
这个函数创建了一个PackageManagerService服务实例,然后把这个服务添加到ServiceManager中去,ServiceManager是Android系统Binder进程间通信机制的守护进程,负责管理系统中的Binder对象,具体可以参考浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路一文。
在创建这个PackageManagerService服务实例时,会在PackageManagerService类的构造函数中开始执行安装应用程序的过程:
view plain
  1. classPackageManagerServiceextendsIPackageManager.Stub{
  2. ......
  3. publicPackageManagerService(Contextcontext,booleanfactoryTest){
  4. ......
  5. synchronized(mInstallLock){
  6. synchronized(mPackages){
  7. ......
  8. FiledataDir=Environment.getDataDirectory();
  9. mAppDataDir=newFile(dataDir,"data");
  10. mSecureAppDataDir=newFile(dataDir,"secure/data");
  11. mDrmAppPrivateInstallDir=newFile(dataDir,"app-private");
  12. ......
  13. mFrameworkDir=newFile(Environment.getRootDirectory(),"framework");
  14. mDalvikCacheDir=newFile(dataDir,"dalvik-cache");
  15. ......
  16. //Findbaseframeworks(resourcepackageswithoutcode).
  17. mFrameworkInstallObserver=newAppDirObserver(
  18. mFrameworkDir.getPath(),OBSERVER_EVENTS,true);
  19. mFrameworkInstallObserver.startWatching();
  20. scanDirLI(mFrameworkDir,PackageParser.PARSE_IS_SYSTEM
  21. |PackageParser.PARSE_IS_SYSTEM_DIR,
  22. scanMode|SCAN_NO_DEX,0);
  23. //Collectallsystempackages.
  24. mSystemAppDir=newFile(Environment.getRootDirectory(),"app");
  25. mSystemInstallObserver=newAppDirObserver(
  26. mSystemAppDir.getPath(),OBSERVER_EVENTS,true);
  27. mSystemInstallObserver.startWatching();
  28. scanDirLI(mSystemAppDir,PackageParser.PARSE_IS_SYSTEM
  29. |PackageParser.PARSE_IS_SYSTEM_DIR,scanMode,0);
  30. //Collectallvendorpackages.
  31. mVendorAppDir=newFile("/vendor/app");
  32. mVendorInstallObserver=newAppDirObserver(
  33. mVendorAppDir.getPath(),OBSERVER_EVENTS,true);
  34. mVendorInstallObserver.startWatching();
  35. scanDirLI(mVendorAppDir,PackageParser.PARSE_IS_SYSTEM
  36. |PackageParser.PARSE_IS_SYSTEM_DIR,scanMode,0);
  37. mAppInstallObserver=newAppDirObserver(
  38. mAppInstallDir.getPath(),OBSERVER_EVENTS,false);
  39. mAppInstallObserver.startWatching();
  40. scanDirLI(mAppInstallDir,0,scanMode,0);
  41. mDrmAppInstallObserver=newAppDirObserver(
  42. mDrmAppPrivateInstallDir.getPath(),OBSERVER_EVENTS,false);
  43. mDrmAppInstallObserver.startWatching();
  44. scanDirLI(mDrmAppPrivateInstallDir,PackageParser.PARSE_FORWARD_LOCK,
  45. scanMode,0);
  46. ......
  47. }
  48. }
  49. }
  50. ......
  51. }
这里会调用scanDirLI函数来扫描移动设备上的下面这五个目录中的Apk文件:

/system/framework

/system/app

/vendor/app

/data/app

/data/app-private

Step 8.PackageManagerService.scanDirLI
这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:

view plain
  1. classPackageManagerServiceextendsIPackageManager.Stub{
  2. ......
  3. privatevoidscanDirLI(Filedir,intflags,intscanMode,longcurrentTime){
  4. String[]files=dir.list();
  5. ......
  6. inti;
  7. for(i=0;i<files.length;i++){
  8. Filefile=newFile(dir,files[i]);
  9. if(!isPackageFilename(files[i])){
  10. //Ignoreentrieswhicharenotapk's
  11. continue;
  12. }
  13. PackageParser.Packagepkg=scanPackageLI(file,
  14. flags|PackageParser.PARSE_MUST_BE_APK,scanMode,currentTime);
  15. //Don'tmessaroundwithappsinsystempartition.
  16. if(pkg==null&&(flags&PackageParser.PARSE_IS_SYSTEM)==0&&
  17. mLastScanError==PackageManager.INSTALL_FAILED_INVALID_APK){
  18. //Deletetheapk
  19. Slog.w(TAG,"Cleaningupfailedinstallof"+file);
  20. file.delete();
  21. }
  22. }
  23. }
  24. ......
  25. }
对于目录中的每一个文件,如果是以后Apk作为后缀名,那么就调用scanPackageLI函数来对它进行解析和安装。

Step 9.PackageManagerService.scanPackageLI

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:

view plain
  1. classPackageManagerServiceextendsIPackageManager.Stub{
  2. ......
  3. privatePackageParser.PackagescanPackageLI(FilescanFile,
  4. intparseFlags,intscanMode,longcurrentTime){
  5. ......
  6. StringscanPath=scanFile.getPath();
  7. parseFlags|=mDefParseFlags;
  8. PackageParserpp=newPackageParser(scanPath);
  9. ......
  10. finalPackageParser.Packagepkg=pp.parsePackage(scanFile,
  11. scanPath,mMetrics,parseFlags);
  12. ......
  13. returnscanPackageLI(pkg,parseFlags,scanMode|SCAN_UPDATE_SIGNATURE,currentTime);
  14. }
  15. ......
  16. }
这个函数首先会为这个Apk文件创建一个PackageParser实例,接着调用这个实例的parsePackage函数来对这个Apk文件进行解析。这个函数最后还会调用另外一个版本的scanPackageLI函数把来解析后得到的应用程序信息保存在PackageManagerService中。

Step 10.PackageParser.parsePackage
这个函数定义在frameworks/base/core/java/android/content/pm/PackageParser.java文件中:

view plain
  1. publicclassPackageParser{
  2. ......
  3. publicPackageparsePackage(FilesourceFile,StringdestCodePath,
  4. DisplayMetricsmetrics,intflags){
  5. ......
  6. mArchiveSourcePath=sourceFile.getPath();
  7. ......
  8. XmlResourceParserparser=null;
  9. AssetManagerassmgr=null;
  10. booleanassetError=true;
  11. try{
  12. assmgr=newAssetManager();
  13. intcookie=assmgr.addAssetPath(mArchiveSourcePath);
  14. if(cookie!=0){
  15. parser=assmgr.openXmlResourceParser(cookie,"AndroidManifest.xml");
  16. assetError=false;
  17. }else{
  18. ......
  19. }
  20. }catch(Exceptione){
  21. ......
  22. }
  23. ......
  24. String[]errorText=newString[1];
  25. Packagepkg=null;
  26. ExceptionerrorException=null;
  27. try{
  28. //XXXXtodo:needtofigureoutcorrectconfiguration.
  29. Resourcesres=newResources(assmgr,metrics,null);
  30. pkg=parsePackage(res,parser,flags,errorText);
  31. }catch(Exceptione){
  32. ......
  33. }
  34. ......
  35. parser.close();
  36. assmgr.close();
  37. //Setcodeandresourcepaths
  38. pkg.mPath=destCodePath;
  39. pkg.mScanPath=mArchiveSourcePath;
  40. //pkg.applicationInfo.sourceDir=destCodePath;
  41. //pkg.applicationInfo.publicSourceDir=destRes;
  42. pkg.mSignatures=null;
  43. returnpkg;
  44. }
  45. ......
  46. }
每一个Apk文件都是一个归档文件,它里面包含了Android应用程序的配置文件AndroidManifest.xml,这里主要就是要对这个配置文件就行解析了,从Apk归档文件中得到这个配置文件后,就调用另一外版本的parsePackage函数对这个应用程序进行解析了:
view plain
  1. publicclassPackageParser{
  2. ......
  3. privatePackageparsePackage(
  4. Resourcesres,XmlResourceParserparser,intflags,String[]outError)
  5. throwsXmlPullParserException,IOException{
  6. ......
  7. StringpkgName=parsePackageName(parser,attrs,flags,outError);
  8. ......
  9. finalPackagepkg=newPackage(pkgName);
  10. ......
  11. inttype;
  12. ......
  13. TypedArraysa=res.obtainAttributes(attrs,
  14. com.android.internal.R.styleable.AndroidManifest);
  15. ......
  16. while((type=parser.next())!=parser.END_DOCUMENT
  17. &&(type!=parser.END_TAG||parser.getDepth()>outerDepth)){
  18. if(type==parser.END_TAG||type==parser.TEXT){
  19. continue;
  20. }
  21. StringtagName=parser.getName();
  22. if(tagName.equals("application")){
  23. ......
  24. if(!parseApplication(pkg,res,parser,attrs,flags,outError)){
  25. returnnull;
  26. }
  27. }elseif(tagName.equals("permission-group")){
  28. ......
  29. }elseif(tagName.equals("permission")){
  30. ......
  31. }elseif(tagName.equals("permission-tree")){
  32. ......
  33. }elseif(tagName.equals("uses-permission")){
  34. ......
  35. }elseif(tagName.equals("uses-configuration")){
  36. ......
  37. }elseif(tagName.equals("uses-feature")){
  38. ......
  39. }elseif(tagName.equals("uses-sdk")){
  40. ......
  41. }elseif(tagName.equals("supports-screens")){
  42. ......
  43. }elseif(tagName.equals("protected-broadcast")){
  44. ......
  45. }elseif(tagName.equals("instrumentation")){
  46. ......
  47. }elseif(tagName.equals("original-package")){
  48. ......
  49. }elseif(tagName.equals("adopt-permissions")){
  50. ......
  51. }elseif(tagName.equals("uses-gl-texture")){
  52. ......
  53. }elseif(tagName.equals("compatible-screens")){
  54. ......
  55. }elseif(tagName.equals("eat-comment")){
  56. ......
  57. }elseif(RIGID_PARSER){
  58. ......
  59. }else{
  60. ......
  61. }
  62. }
  63. ......
  64. returnpkg;
  65. }
  66. ......
  67. }
这里就是对AndroidManifest.xml文件中的各个标签进行解析了,各个标签的含义可以参考官方文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值