pm,即package manager, 还记得Android Framework层的PackageManager吗?利用PackageManager,可以访问到PackageManagerService。
本篇分析pm命令的源码,与“Android源码分析-am命令的实现”形成姊妹篇。
pm命令的使用:
一个简单的pm命令: 列出已经安装的第三方packagename(包名)
$ pm list package -3$ pm list package -3 package:com.test.mydemofrag2 package:com.example.myapp package:com.test.mytestapp
pm命令的用法:
再看一个例子: 列出系统库
pm源码分析:
源码位置:
frameworks/base/cmds/pm
Pm类(Pm.java)就是pm命令的代码实现,我们主要来分析这个java文件。
Pm类的主要数据成员和部分方法:
数据成员:IPackageManager mPm; //即PackageManager在client端的实例,用于与PackageManagerService通过binder进行通信,主要功能都是通过它来实现; private WeakHashMap<String, Resources> mResourceCache = new WeakHashMap<String, Resources>();//资源文件缓存 private String[] mArgs;//pm命令的参数
方法:
1. run方法:
初始化mPm以及进行命令行解析。
初始化mPm:
mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
2. runListLibraries方法:
获取系统库(即jar包,而非so)
String[] rawList = mPm.getSystemSharedLibraryNames();
3.runListPackages:列出包名
以pm list package -3为例:
final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags); int count = packages.size(); for (int p = 0 ; p < count ; p++) { PackageInfo info = packages.get(p); if (filter != null && !info.packageName.contains(filter)) { continue; } final boolean isSystem = (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; if ((!listDisabled || !info.applicationInfo.enabled) && (!listEnabled || info.applicationInfo.enabled) && (!listSystem || isSystem) && (!listThirdParty || !isSystem)) { System.out.print("package:"); if (showApplicationPackage) { System.out.print(info.applicationInfo.sourceDir); System.out.print("="); } System.out.print(info.packageName); if (listInstaller) { System.out.print(" installer="); System.out.print(mPm.getInstallerPackageName(info.packageName)); } System.out.println(); } }
mPm.getInstallerPackageName(info.packageName), 用于获取package list。
可见,主要功能都是通过mPm来实现的,而mPm真正的实例是ApplicationPackageManager:
final class ApplicationPackageManager extends PackageManager {......
}PackageManager是抽象类,ApplicationPackageManager是具体的实现类。