首页 文章 精选 留言 我的

精选列表

搜索[动态代码分析],共10050篇文章
优秀的个人博客,低调大师

Android应用程序安装过程源代码分析(3)

Step 7.PackageManagerService.main 这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中: [cpp] view plain copy classPackageManagerServiceextendsIPackageManager.Stub{ ...... publicstaticfinalIPackageManagermain(Contextcontext,booleanfactoryTest){ PackageManagerServicem=newPackageManagerService(context,factoryTest); ServiceManager.addService("package",m); returnm; } ...... } 这个函数创建了一个PackageManagerService服务实例,然后把这个服务添加到ServiceManager中去,ServiceManager是Android系统Binder进程间通信机制的守护进程,负责管理系统中的Binder对象,具体可以参考 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路 一文。 在创建这个PackageManagerService服务实例时,会在PackageManagerService类的构造函数中开始执行安装应用程序的过程: [java] view plain copy classPackageManagerServiceextendsIPackageManager.Stub{ ...... publicPackageManagerService(Contextcontext,booleanfactoryTest){ ...... synchronized(mInstallLock){ synchronized(mPackages){ ...... FiledataDir=Environment.getDataDirectory(); mAppDataDir=newFile(dataDir,"data"); mSecureAppDataDir=newFile(dataDir,"secure/data"); mDrmAppPrivateInstallDir=newFile(dataDir,"app-private"); ...... mFrameworkDir=newFile(Environment.getRootDirectory(),"framework"); mDalvikCacheDir=newFile(dataDir,"dalvik-cache"); ...... //Findbaseframeworks(resourcepackageswithoutcode). mFrameworkInstallObserver=newAppDirObserver( mFrameworkDir.getPath(),OBSERVER_EVENTS,true); mFrameworkInstallObserver.startWatching(); scanDirLI(mFrameworkDir,PackageParser.PARSE_IS_SYSTEM |PackageParser.PARSE_IS_SYSTEM_DIR, scanMode|SCAN_NO_DEX,0); //Collectallsystempackages. mSystemAppDir=newFile(Environment.getRootDirectory(),"app"); mSystemInstallObserver=newAppDirObserver( mSystemAppDir.getPath(),OBSERVER_EVENTS,true); mSystemInstallObserver.startWatching(); scanDirLI(mSystemAppDir,PackageParser.PARSE_IS_SYSTEM |PackageParser.PARSE_IS_SYSTEM_DIR,scanMode,0); //Collectallvendorpackages. mVendorAppDir=newFile("/vendor/app"); mVendorInstallObserver=newAppDirObserver( mVendorAppDir.getPath(),OBSERVER_EVENTS,true); mVendorInstallObserver.startWatching(); scanDirLI(mVendorAppDir,PackageParser.PARSE_IS_SYSTEM |PackageParser.PARSE_IS_SYSTEM_DIR,scanMode,0); mAppInstallObserver=newAppDirObserver( mAppInstallDir.getPath(),OBSERVER_EVENTS,false); mAppInstallObserver.startWatching(); scanDirLI(mAppInstallDir,0,scanMode,0); mDrmAppInstallObserver=newAppDirObserver( mDrmAppPrivateInstallDir.getPath(),OBSERVER_EVENTS,false); mDrmAppInstallObserver.startWatching(); scanDirLI(mDrmAppPrivateInstallDir,PackageParser.PARSE_FORWARD_LOCK, scanMode,0); ...... } } } ...... } 这里会调用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文件中: [java] view plain copy classPackageManagerServiceextendsIPackageManager.Stub{ ...... privatevoidscanDirLI(Filedir,intflags,intscanMode,longcurrentTime){ String[]files=dir.list(); ...... inti; for(i=0;i<files.length;i++){ Filefile=newFile(dir,files[i]); if(!isPackageFilename(files[i])){ //Ignoreentrieswhicharenotapk's continue; } PackageParser.Packagepkg=scanPackageLI(file, flags|PackageParser.PARSE_MUST_BE_APK,scanMode,currentTime); //Don'tmessaroundwithappsinsystempartition. if(pkg==null&&(flags&PackageParser.PARSE_IS_SYSTEM)==0&& mLastScanError==PackageManager.INSTALL_FAILED_INVALID_APK){ //Deletetheapk Slog.w(TAG,"Cleaningupfailedinstallof"+file); file.delete(); } } } ...... } 对于目录中的每一个文件,如果是以后Apk作为后缀名,那么就调用scanPackageLI函数来对它进行解析和安装。 Step 9.PackageManagerService.scanPackageLI 这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中: [java] view plain copy classPackageManagerServiceextendsIPackageManager.Stub{ ...... privatePackageParser.PackagescanPackageLI(FilescanFile, intparseFlags,intscanMode,longcurrentTime){ ...... StringscanPath=scanFile.getPath(); parseFlags|=mDefParseFlags; PackageParserpp=newPackageParser(scanPath); ...... finalPackageParser.Packagepkg=pp.parsePackage(scanFile, scanPath,mMetrics,parseFlags); ...... returnscanPackageLI(pkg,parseFlags,scanMode|SCAN_UPDATE_SIGNATURE,currentTime); } ...... } 这个函数首先会为这个Apk文件创建一个PackageParser实例,接着调用这个实例的parsePackage函数来对这个Apk文件进行解析。这个函数最后还会调用另外一个版本的scanPackageLI函数把来解析后得到的应用程序信息保存在PackageManagerService中。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966522,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序启动过程源代码分析(5)

Step 35. MainActivity.onCreate 这个函数定义在packages/experimental/Activity/src/shy/luo/activity/MainActivity.java文件中,这是我们自定义的app工程文件: publicclassMainActivityextendsActivityimplementsOnClickListener{ ...... @Override publicvoidonCreate(BundlesavedInstanceState){ ...... Log.i(LOG_TAG,"MainActivityCreated."); } ...... } 这样,MainActivity就启动起来了,整个应用程序也启动起来了。 整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段: 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity; 二. Step 12 - Step 16:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态; 三. Step 17 - Step 24:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行; 四. Step 25 - Step 27:ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信; 五. Step 28 - Step 35:ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。 这里不少地方涉及到了Binder进程间通信机制,相关资料请参考Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。 这样,应用程序的启动过程就介绍完了,它实质上是启动应用程序的默认Activity,在下一篇文章中,我们将介绍在应用程序内部启动另一个Activity的过程,即新的Activity与启动它的Activity将会在同一个进程(Process)和任务(Task)运行,敬请关注。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/965993,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序安装过程源代码分析(4)

Step 12.PackageManagerService.scanPackageLI 这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中: [java] view plain copy classPackageManagerServiceextendsIPackageManager.Stub{ ...... //KeysareString(packagename),valuesarePackage.Thisalsoserves //asthelockfortheglobalstate.Methodsthatmustbecalledwith //thislockheldhavetheprefix"LP". finalHashMap<String,PackageParser.Package>mPackages= newHashMap<String,PackageParser.Package>(); ...... //Allavailableactivities,foryourresolvingpleasure. finalActivityIntentResolvermActivities= newActivityIntentResolver(); //Allavailablereceivers,foryourresolvingpleasure. finalActivityIntentResolvermReceivers= newActivityIntentResolver(); //Allavailableservices,foryourresolvingpleasure. finalServiceIntentResolvermServices=newServiceIntentResolver(); //KeysareString(providerclassname),valuesareProvider. finalHashMap<ComponentName,PackageParser.Provider>mProvidersByComponent= newHashMap<ComponentName,PackageParser.Provider>(); ...... privatePackageParser.PackagescanPackageLI(PackageParser.Packagepkg, intparseFlags,intscanMode,longcurrentTime){ ...... synchronized(mPackages){ ...... //AddthenewsettingtomPackages mPackages.put(pkg.applicationInfo.packageName,pkg); ...... intN=pkg.providers.size(); inti; for(i=0;i<N;i++){ PackageParser.Providerp=pkg.providers.get(i); p.info.processName=fixProcessName(pkg.applicationInfo.processName, p.info.processName,pkg.applicationInfo.uid); mProvidersByComponent.put(newComponentName(p.info.packageName, p.info.name),p); ...... } N=pkg.services.size(); for(i=0;i<N;i++){ PackageParser.Services=pkg.services.get(i); s.info.processName=fixProcessName(pkg.applicationInfo.processName, s.info.processName,pkg.applicationInfo.uid); mServices.addService(s); ...... } N=pkg.receivers.size(); r=null; for(i=0;i<N;i++){ PackageParser.Activitya=pkg.receivers.get(i); a.info.processName=fixProcessName(pkg.applicationInfo.processName, a.info.processName,pkg.applicationInfo.uid); mReceivers.addActivity(a,"receiver"); ...... } N=pkg.activities.size(); for(i=0;i<N;i++){ PackageParser.Activitya=pkg.activities.get(i); a.info.processName=fixProcessName(pkg.applicationInfo.processName, a.info.processName,pkg.applicationInfo.uid); mActivities.addActivity(a,"activity"); ...... } ...... } ...... returnpkg; } ...... } 这个函数主要就是把前面解析应用程序得到的package、provider、service、receiver和activity等信息保存在PackageManagerService服务中了。 这样,在Android系统启动的时候安装应用程序的过程就介绍完了,但是,这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了,在下一篇文章中,我们将介绍Launcher是如何启动的以及它是如何从PackageManagerService服务中把系统中已经安装好的应用程序展现出来的,敬请期待。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966524,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序安装过程源代码分析(2)

Step 4. AndroidRuntime.callStatic 这个函数定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中: [cpp] view plain copy /* *CallastaticJavaProgrammingLanguagefunctionthattakesnoargumentsandreturnsvoid. */ status_tAndroidRuntime::callStatic(constchar*className,constchar*methodName) { JNIEnv*env; jclassclazz; jmethodIDmethodId; env=getJNIEnv(); if(env==NULL) returnUNKNOWN_ERROR; clazz=findClass(env,className); if(clazz==NULL){ LOGE("ERROR:couldnotfindclass'%s'\n",className); returnUNKNOWN_ERROR; } methodId=env->GetStaticMethodID(clazz,methodName,"()V"); if(methodId==NULL){ LOGE("ERROR:couldnotfindmethod%s.%s\n",className,methodName); returnUNKNOWN_ERROR; } env->CallStaticVoidMethod(clazz,methodId); returnNO_ERROR; } 这个函数调用由参数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文件中: [java] view plain copy publicclassSystemServer { ...... publicstaticfinalvoidinit2(){ Slog.i(TAG,"EnteredtheAndroidsystemserver!"); Threadthr=newServerThread(); thr.setName("android.server.ServerThread"); thr.start(); } } 这个函数创建了一个ServerThread线程,PackageManagerService服务就是这个线程中启动的了。这里调用了ServerThread实例thr的start函数之后,下面就会执行这个实例的run函数了。 Step 6.ServerThread.run 这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中: [java] view plain copy classServerThreadextendsThread{ ...... @Override publicvoidrun(){ ...... IPackageManagerpm=null; ...... //Criticalservices... try{ ...... Slog.i(TAG,"PackageManager"); pm=PackageManagerService.main(context, factoryTest!=SystemServer.FACTORY_TEST_OFF); ...... }catch(RuntimeExceptione){ Slog.e("System","Failurestartingcoreservice",e); } ...... } ...... } 这个函数除了启动PackageManagerService服务之外,还启动了其它很多的服务,例如在前面学习Activity和Service的几篇文章中经常看到的ActivityManagerService服务,有兴趣的读者可以自己研究一下。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966521,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册