`

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. /*
  8. *JNIregistration.
  9. */
  10. staticJNINativeMethodgMethods[]={
  11. /*name,signature,funcPtr*/
  12. {"init1","([Ljava/lang/String;)V",(void*)android_server_SystemServer_init1},
  13. };
  14. intregister_android_server_SystemServer(JNIEnv*env)
  15. {
  16. returnjniRegisterNativeMethods(env,"com/android/server/SystemServer",
  17. gMethods,NELEM(gMethods));
  18. }
  19. };//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. /*
  2. *CallastaticJavaProgrammingLanguagefunctionthattakesnoargumentsandreturnsvoid.
  3. */
  4. status_tAndroidRuntime::callStatic(constchar*className,constchar*methodName)
  5. {
  6. JNIEnv*env;
  7. jclassclazz;
  8. jmethodIDmethodId;
  9. env=getJNIEnv();
  10. if(env==NULL)
  11. returnUNKNOWN_ERROR;
  12. clazz=findClass(env,className);
  13. if(clazz==NULL){
  14. LOGE("ERROR:couldnotfindclass'%s'\n",className);
  15. returnUNKNOWN_ERROR;
  16. }
  17. methodId=env->GetStaticMethodID(clazz,methodName,"()V");
  18. if(methodId==NULL){
  19. LOGE("ERROR:couldnotfindmethod%s.%s\n",className,methodName);
  20. returnUNKNOWN_ERROR;
  21. }
  22. env->CallStaticVoidMethod(clazz,methodId);
  23. returnNO_ERROR;
  24. }
这个函数调用由参数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文件中的各个标签进行解析了,各个标签的含义可以参考官方文档http://developer.android.com/guide/topics/manifest/manifest-intro.html,这里我们只简单看一下application标签的解析,这是通过调用parseApplication函数来进行的。

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

view plain
  1. publicclassPackageParser{
  2. ......
  3. privatebooleanparseApplication(Packageowner,Resourcesres,
  4. XmlPullParserparser,AttributeSetattrs,intflags,String[]outError)
  5. throwsXmlPullParserException,IOException{
  6. finalApplicationInfoai=owner.applicationInfo;
  7. finalStringpkgName=owner.applicationInfo.packageName;
  8. TypedArraysa=res.obtainAttributes(attrs,
  9. com.android.internal.R.styleable.AndroidManifestApplication);
  10. ......
  11. inttype;
  12. while((type=parser.next())!=parser.END_DOCUMENT
  13. &&(type!=parser.END_TAG||parser.getDepth()>innerDepth)){
  14. if(type==parser.END_TAG||type==parser.TEXT){
  15. continue;
  16. }
  17. StringtagName=parser.getName();
  18. if(tagName.equals("activity")){
  19. Activitya=parseActivity(owner,res,parser,attrs,flags,outError,false);
  20. ......
  21. owner.activities.add(a);
  22. }elseif(tagName.equals("receiver")){
  23. Activitya=parseActivity(owner,res,parser,attrs,flags,outError,true);
  24. ......
  25. owner.receivers.add(a);
  26. }elseif(tagName.equals("service")){
  27. Services=parseService(owner,res,parser,attrs,flags,outError);
  28. ......
  29. owner.services.add(s);
  30. }elseif(tagName.equals("provider")){
  31. Providerp=parseProvider(owner,res,parser,attrs,flags,outError);
  32. ......
  33. owner.providers.add(p);
  34. }elseif(tagName.equals("activity-alias")){
  35. Activitya=parseActivityAlias(owner,res,parser,attrs,flags,outError);
  36. ......
  37. owner.activities.add(a);
  38. }elseif(parser.getName().equals("meta-data")){
  39. ......
  40. }elseif(tagName.equals("uses-library")){
  41. ......
  42. }elseif(tagName.equals("uses-package")){
  43. ......
  44. }else{
  45. ......
  46. }
  47. }
  48. returntrue;
  49. }
  50. ......
  51. }
这里就是对AndroidManifest.xml文件中的application标签进行解析了,我们常用到的标签就有activity、service、receiver和provider,各个标签的含义可以参考官方文档http://developer.android.com/guide/topics/manifest/manifest-intro.html。

这里解析完成后,一层层返回到Step 9中,调用另一个版本的scanPackageLI函数把来解析后得到的应用程序信息保存下来。

Step 12.PackageManagerService.scanPackageLI

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

view plain
  1. classPackageManagerServiceextendsIPackageManager.Stub{
  2. ......
  3. //KeysareString(packagename),valuesarePackage.Thisalsoserves
  4. //asthelockfortheglobalstate.Methodsthatmustbecalledwith
  5. //thislockheldhavetheprefix"LP".
  6. finalHashMap<String,PackageParser.Package>mPackages=
  7. newHashMap<String,PackageParser.Package>();
  8. ......
  9. //Allavailableactivities,foryourresolvingpleasure.
  10. finalActivityIntentResolvermActivities=
  11. newActivityIntentResolver();
  12. //Allavailablereceivers,foryourresolvingpleasure.
  13. finalActivityIntentResolvermReceivers=
  14. newActivityIntentResolver();
  15. //Allavailableservices,foryourresolvingpleasure.
  16. finalServiceIntentResolvermServices=newServiceIntentResolver();
  17. //KeysareString(providerclassname),valuesareProvider.
  18. finalHashMap<ComponentName,PackageParser.Provider>mProvidersByComponent=
  19. newHashMap<ComponentName,PackageParser.Provider>();
  20. ......
  21. privatePackageParser.PackagescanPackageLI(PackageParser.Packagepkg,
  22. intparseFlags,intscanMode,longcurrentTime){
  23. ......
  24. synchronized(mPackages){
  25. ......
  26. //AddthenewsettingtomPackages
  27. mPackages.put(pkg.applicationInfo.packageName,pkg);
  28. ......
  29. intN=pkg.providers.size();
  30. inti;
  31. for(i=0;i<N;i++){
  32. PackageParser.Providerp=pkg.providers.get(i);
  33. p.info.processName=fixProcessName(pkg.applicationInfo.processName,
  34. p.info.processName,pkg.applicationInfo.uid);
  35. mProvidersByComponent.put(newComponentName(p.info.packageName,
  36. p.info.name),p);
  37. ......
  38. }
  39. N=pkg.services.size();
  40. for(i=0;i<N;i++){
  41. PackageParser.Services=pkg.services.get(i);
  42. s.info.processName=fixProcessName(pkg.applicationInfo.processName,
  43. s.info.processName,pkg.applicationInfo.uid);
  44. mServices.addService(s);
  45. ......
  46. }
  47. N=pkg.receivers.size();
  48. r=null;
  49. for(i=0;i<N;i++){
  50. PackageParser.Activitya=pkg.receivers.get(i);
  51. a.info.processName=fixProcessName(pkg.applicationInfo.processName,
  52. a.info.processName,pkg.applicationInfo.uid);
  53. mReceivers.addActivity(a,"receiver");
  54. ......
  55. }
  56. N=pkg.activities.size();
  57. for(i=0;i<N;i++){
  58. PackageParser.Activitya=pkg.activities.get(i);
  59. a.info.processName=fixProcessName(pkg.applicationInfo.processName,
  60. a.info.processName,pkg.applicationInfo.uid);
  61. mActivities.addActivity(a,"activity");
  62. ......
  63. }
  64. ......
  65. }
  66. ......
  67. returnpkg;
  68. }
  69. ......
  70. }

这个函数主要就是把前面解析应用程序得到的package、provider、service、receiver和activity等信息保存在PackageManagerService服务中了。

这样,在Android系统启动的时候安装应用程序的过程就介绍完了,但是,这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了,在下一篇文章中,我们将介绍Launcher是如何启动的以及它是如何从PackageManagerService服务中把系统中已经安装好的应用程序展现出来的,敬请期待。


分享到:
评论
1 楼 sjp524617477 2012-03-29  
强大,先看看

相关推荐

    老罗的android之旅时序图

    Android系统默认Home应用程序(Launcher)的启动过程源代码分析uml,Android系统在新进程中启动自定义服务过程(startService)的原理分析UML,Android应用程序安装过程源代码分析UML.jpg,Android应用程序绑定服务...

    Android应用程序设计 (张思民 编著) pdf

    《21世纪高等学校计算机基础实用规划教材:Android应用程序设计》是面向Android系统的初学者的入门教程,内容几乎涵盖了Android相关的所有技术。本书大致可以分成两个部分,第一部分(第1~4章)主要介绍Android SDK...

    Android系统源代码情景分析 / 罗升阳著

     在组织上,《Android系统源代码情景分析(含CD光盘1张)》将上述内容划分为初识Android系统、Android专用驱动系统和Android应用程序框架三大篇。初识Android系统篇介绍了参考书籍、基础知识以及实验环境搭建;...

    《Android系统源代码情景分析》

    《Android系统源代码情景分析》随书光盘内容(源代码) 目录如下: 第1篇 初识Android系统 ...第16章 Android应用程序的安装和显示过程 16.1 应用程序的安装过程 16.2 应用程序的显示过程

    88个经典Android应用程序打包下载

    88个经典Android应用程序打包下载 学习Android必备代码

    Android系统源代码情景分析-罗升阳-源码

    《Android系统源代码情景分析》随书光盘内容(源代码) 目录如下: 第1篇 初识Android系统 第1章 准备知识 ...第16章 Android应用程序的安装和显示过程 16.1 应用程序的安装过程 16.2 应用程序的显示过程

    Android系统源代码情景分析[罗升阳著]pdf完整清晰版

    Android应用程序框架篇从组件、进程、消息以及安装四个维度来对Android应用程序的框架进行了深入的剖析。, 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上去掌握每一个...

    Android系统源代码情景分析 PDF 完整版 ZIP.002(二个压缩包)

    Android应用程序框架篇从组件、进程、消息以及安装四个维度来对Android应用程序的框架进行了深入的剖析。 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上去掌握每一个层次...

    Android高级编程--源代码

    3.1 Android应用程序的组成部分 43 3.2 程序清单简介 44 3.3 使用清单编辑器 47 3.4 Android应用程序生命周期 48 3.5 理解应用程序的优先级和进程状态 49 3.6 分离资源 50 3.6.1 创建资源 50 3.6.2 使用资源...

    Android系统源代码情景分析 [罗升阳 著] [高清版 带书签 840页]

    Android应用程序框架篇从组件、进程、消息以及安装四个维度对Android应用程序的框架进行了深入的剖析。 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上掌握每一个层次的...

    《Android系统源代码情景分析》 PDF

    在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...

    Android系统源代码情景分析 【罗升阳】

    罗升阳,2007年毕业于浙江大学计算机系,2010年毕业于上海交通大学计算机系,在国内知名IT技术社区CSDN上发表...Android应用程序框架篇从组件、进程、消息以及安装四个维度来对Android应用程序的框架进行了深入的剖析。

    Android应用源码之程序的安装、卸载和更新.zip

    Android应用源码之程序的安装、卸载和更新

    罗升阳-Android系统源代码情景分析(带书签完整高清版).pdf

    Android应用程序框架篇从组件、进程、消息以及安装四个维度对Android应用程序的框架进行了深入的剖析。 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上掌握每一个层次的...

    Android系统源代码情景分析光盘

    Android系统源代码情景分析光盘资料 目录 第1篇初识Android系统 第1章 准备知识................................................................ 2 1.1 Linux内核参考书籍......................................

    Android开发应用实战详解源代码

    1.1.4 android应用程序框架 1.1.5 android的竞争优势 1.1.6 android模拟器 1.2 搭建android开发环境 1.2.1 准备工作 1.2.2 windows系统下的搭建过程 1.2.3 linux系统下的搭建过程 1.3 常见问题汇总 1.4 使用本书的...

    Android系统源代码情景分析》光盘内容

    Android应用程序框架篇从组件、进程、消息以及安装四个维度对Android应用程序的框架进行了深入的剖析。 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上掌握每一个层次的...

    android 情景分析源代码

    在内容上,本书结合使用情景,全面、深入、细致地分析了Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application...

    Android系统源代码情景分析 [罗升阳著]

    Android应用程序框架篇从组件、进程、消息以及安装四个维度对Android应用程序的框架进行了深入的剖析。 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上掌握每一个层次的...

    android系统应用程序源码

    本人想学习android1.5中系统应用程序如:联系人,发邮件,googlesearch,摄像,闹钟,日历,Mms,Music,Settings,Phone,Browser,HTMLViewer,IM等等android系统自带的应用程序.发现网上没有这些源码下载,于是自己用了...

Global site tag (gtag.js) - Google Analytics