PackageManager分析.docx_第1页
PackageManager分析.docx_第2页
PackageManager分析.docx_第3页
PackageManager分析.docx_第4页
PackageManager分析.docx_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

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

文档简介

1. PackageManager.java是一个抽象类,在frameworksbasecorejavaandroidcontentpmPackageManager.java中定义,其中只定义了所有在SDK中声明的抽象方法,还有一些静态常量。activity manager等其他部分都是调用这个抽象类的接口来做工作的,也就是说这个抽象类是Package Manager跟其他部分的对外接口:public abstract class PackageManager .2. .实现PackageManager这个抽象类的是frameworksbasecorejavaandroidapp下面的ApplicationPackageManager.java:static final class ApplicationPackageManager extends PackageManager 实际上,frameworksbasecorejavaandroidapp这个目录下面就是所有的app会使用到的类啦,包括activity manager等。而ApplicationPackageManager这个类又是通过调用IPackageManager这个接口中的函数来实现相应功能的。举例来讲,对于getPackageInfo这个routine,ApplicationPackageManager的实现如下: public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException try PackageInfo pi = mPM.getPackageInfo(packageName, flags); if (pi != null) return pi; catch (RemoteException e) throw new RuntimeException(Package manager has died, e);/从这里也可以看出,这是对一个service的远程调用 throw new NameNotFoundException(packageName); 这个mPM就是IPackageManager,是ApplicationPackageManager这个类的一个成员,定义为:private final IPackageManager mPM;对于其他的方法,也是如此,基本上都是对IPackageManager的封装调用。3. 而IPackageManager是一个AIDL定义的接口,其是在IPackageManager.java文件中定义的,这个java文件在source code tree中并不存在,是在编译的时候由aidl编译系统根据aidl文件自动生成的(有关aidl的内容,请参考dev guide),这个aidl文件就是frameworksbasecorejavaandroidcontentpm下的IPackageManager.aidl。可是我们知道,java中的接口也是要有实现的,而对于IPackageManager这个接口的实现就是Package Manager中最重要的Package Manager Service啦:class PackageManagerService extends IPackageManager.Stub 所以,我们平时对PackageManager的调用,最终都是会调到在PackageManagerService这个class中实现的函数,而这个PackageManagerService类是在frameworksbaseservicesjavacomandroidserverpmPackageManagerService.java中定义的。在PackageManagerService.java中对每个方法的实现,会用到一些隐藏的android内部使用的类和方法。4. 在system thread开始运行之后(frameworksbaseservicesjavacomandroidserver SystemServer.java中定义system thread,这个thread运行起来就是执行其run函数),在这个thread的run函数中会做如下的调用: pm = PackageManagerService.main(context, factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore);其中,返回的pm就是一个IPackageManager结构,pm就是system thread对应的class ServerThread的一个成员啦,而系统中只有一个system thread,也就是只有一个class ServerThread实例。在PackageManagerService.java中定义的main函数的定义为:public static final IPackageManager main(Context context, boolean factoryTest, boolean onlyCore) PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore); ServiceManager.addService(package, m); return m;也就是两件事情,创建一个PackageManagerService class的实例,这个实例以IPackageManager接口来表示,保存在了class ServerThread实例的pm成员中;另外就是把这个PackageManagerService以package为名字给注册到系统中去。那么,在其他的APP中如果需要使用这个IPackageManager接口,就可以使用IPackageManager.Stub.asInterface(ServiceManager.getService(package)这样的调用来获得这个PackageManagerService实例所对应的IPackageManager接口了。但是,最常用的还是要从PackageManager到PackageManagerService,这个基本上就是通过context class的getPackageManager方法,也就是mContext.getPackageManager()调用,而每个APP基本上都会有一个context的,也就是其上下文环境。这个context抽象类的实现就是/frameworks/base/core/java/android/app下面的ContextImpl.java,它会创建一个ApplicationPackageManager实例,但都是最终通过getService(“package”)来获得PackageManagerService实例并将其赋值给ApplicationPackageManager类的mPM成员,这样调用这里实例化的PackageManager类方法时,最终也还是调用到PackageManagerService类的那个唯一实例中去的,从而可以保证虽然有多个PackageManager实例,但最终都是只有一个PackageManagerService实例,这才是service的意义所在嘛,service就是为所有人服务的,不能给每一个人都创建一个实例,这样就不叫server啦。5. 总之,其他的APP要使用Package Manager的时候,要通过GetPackageManager方法来请求PackageManagerService这个System Service,保证有系统中只有一个PackageManagerService实例,同时获得PackageManager class的实例。然后进入PackageManager这个抽象类的实现类,即class ApplicationPackageManager。在ApplicationPackageManager中的实现,都是对IPackageManager接口的调用,这是一个aidl接口,也就是说它肯定对应某一个service,来进行远程调用。而这个service就是最终的实现类,它就是PackageManagerService。通过了这么一个复杂的流程,最终就是来到了PackageManagerService这个class。1.PackageManagerService.java用到一个很重要的工具类,PackageParser.java。这里面是一些工具类和工具方法,辅助PackageManagerService来完成一些功能,具体代码自己去看一下。下面仔细分析一下PackageManagerService的启动流程。1.PackageManagerService中有一个静态方法:main()。生成一个IPackageManager接口,也就是PackageManagerService。下面我们主要看PackageManagerService的构造方法。public static final IPackageManager main(Context context, boolean factoryTest) PackageManagerService m = new PackageManagerService(context, factoryTest); ServiceManager.addService(package, m); return m; 2.构造方法中,首先会进行一些成员变量的初始化,比如mContext, mFactoryTest, mMetrics, mSettings等。最重要的是初始化mInstaller这个变量。Installer是一个很重要的类,所有对apk的install, uninstall,move等操作,都是通过它进行的。在下一篇中,会分析它。 Installer installer = new Installer(); if (installer.ping() & Process.supportsProcesses() mInstaller = installer; else mInstaller = null; 3.建立PackageHandler消息循环,用于处理外部的apk安装请求消息,如adb install,packageinstaller安装apk时会发送消息 mHandlerThread.start(); mHandler = new PackageHandler(mHandlerThread.getLooper();4.解析/system/etc/permission下xml文件(framework/base/data/etc/),包括platform.xml和系统支持的各种硬件模块的feature.主要工作:(1)建立底层user ids和group ids 同上层permissions之间的映射;可以指定一个权限与几个组ID对应。当一个APK被授予这个权限时,它也同时属于这几个组。(2)给一些底层用户分配权限,如给shell授予各种permission权限;把一个权限赋予一个UID,当进程使用这个UID运行时,就具备了这个权限。(3) library,系统增加的一些应用需要link的扩展jar库;(4) feature,系统每增加一个硬件,都要添加相应的feature.将解析结果放入mSystemPermissions,mSharedLibraries,mSettings.mPermissions,mAvailableFeatures等几个集合中供系统查询和权限配置使用。5.检查/data/system/packages.xml是否存在,这个文件是在解析apk时由writeLP()创建的,里面记录了系统的permissions,以及每个apk的name,codePath,flags,ts,version,uesrid等信息,这些信息主要通过apk的AndroidManifest.xml解析获取,解析完apk后将更新信息写入这个文件并保存到flash,下次开机直接从里面读取相关信息添加到内存相关列表中。当有apk升级,安装或删除时会更新这个文件。6.检查BootClassPath,mSharedLibraries及/system/framework下的jar是否需要dexopt,需要的则通过dexopt进行优化7.启动AppDirObserver线程监测/system/framework,/system/app,/data/app,/data/app-private目录的事件,主要监听add和remove事件。对于目录监听底层通过inotify机制实现,inotify 是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户态得知,它为用户态监视文件系统的变化提供了强大的支持。当有add event时调用scanPackageLI(File , int , int)处理;当有remove event时调用removePackageLI()处理;8.对于以上几个目录下的apk逐个解析,主要是解析每个apk的AndroidMa-nifest.xml文件,处理asset/res等资源文件,建立起每个apk的配置结构信息,并将每个apk的配置信息添加到全局列表进行管理。调用installer.install()进行安装工作,检查apk里的dex文件是否需要再优化,如果需要优化则通过辅助工具dexopt进行优化处理;将解析出的componet添加到pkg的对应列表里;对apk进行签名和证书校验,进行完整性验证。9.将解析的每个apk的信息保存到packages.xml和packages.list文件里,packages.list记录了如下数据:pkgName,userId,debugFlag,dataPath(包的数据路径)Installer类分析。1.Installer这个是PackageManager与底层C模块进行通信的工具类,同socket进行通信,PackageManager所有对apk的安装,卸载等操作都是通过Installer进行的。2.对Installer的调用首先会调用ping()来判断socket是否已经连接。3.连接方法:connect()。 mSocket = new LocalSocket(); LocalSocketAddress address = new LocalSocketAddress( installd, LocalSocketAddress.Namespace.RESERVED); mSocket.connect(address);连接socket文件installd。4.断开方法:disconnect()。 if (mSocket != null) mSocket.close(); 5.对socket文件的读写工具方法:readBytes(byte buffer, int len);readReply();writeCommand(String _cmd);这些方法都是对socket文件进行读写,比如将命令写入socket文件,读取返回信息。6.执行命令的方法:execute(String cmd); private int execute(String cmd) String res = transaction(cmd); try return Integer.parseInt(res); catch (NumberFormatException ex) return -1; 执行cmd的命令字符串。7.transaction(String cmd);transaction首先会判断连接,如果socket连接正常,就将cmd命令写入socket文件,并且接收返回信息,并且返回给execute。8.对apk进行操作的方法一共有如下几个:(1)install(String name, int uid, int gid);安装apk(2)dexopt(String apkPath, int uid, boolean isPublic);优化dex文件(3)movedex(String srcPath, String dstPath);移动dex文件(4)rmdex(String codePath);删除dex文件(5)remove(String name);移动apk(6)rename(String oldname, String newname);重命名(7)deleteCacheFiles(String name);删除cache文件(8)clearUserData(String name);删除user data(9)freeCache(long freeStorageSize);释放cache空间(10)setForwardLockPerm(String packagePathSuffix, int gid)为apk文件增加前缀(11)getSizeInfo(String pkgName, String apkPath, String fwdLockApkPath, PackageStats pStats) 获取apk信息(12) moveFiles();移动文件。pakcage install 过程分析1.调用安装的接口有两个。public void installPackage( final Uri packageURI, final IPackageInstallObserver observer, final int flags) installPackage(packageURI, observer, flags, null); public void installPackage( final Uri packageURI, final IPackageInstallObserver observer, final int flags, final String installerPackageName);可以看到第一个接口直接调用了第二个接口,只是最后一个参数传了null。下面解释一下每个参数:packageURI:apk文件的Uri。observer:从名字可以看出, IPackageInstallObserver,是为了监听安装完成以后的监听器。需要创建一个IPackageInstallObserver对象传进来,监听安装结果,最后会给出一个完整的安装例子。flags:安装的一些标志,比如是否覆盖安装等,这些标志在PackageManager中有常量标示。installerPackageName:为调用安装接口的调用者,可以为null。2.installPackage()的实现很简单,首先通过mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);来判断一

温馨提示

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

评论

0/150

提交评论