PackageManger这个类用于获取与设备当前已安装应用包相关的各种信息。接着从功能、框架及使用几个方面对它进行简要的介绍,供大家学习和参考。
先看下PackageManger官方说明:
Class for retrieving various kinds of information related to the application packages that are currently installed on the device. You can find this class through getPackageManager()
.
大体意思就是这个类可用于获取与设备当前已安装应用包相关的各种信息,我们可以通过getPackageManager()
使用它。
PackageManger功能:
- 应用的安装、卸载与查询
- permission的增加、删除和查询
-
查询Application相关信息(application,activity,receiver,service,provider及相应属性等)
-
清除用户数据、缓存,代码段等
PackageManager框架
静态类图如下:
大部分情况我们是在Activity中使用getPackageManager方法获取一个ApplicationPackageManager的对象,ApplicationPackageManager实际上是包装了一个IPackageManager.Stub.Proxy的对象,由IPackageManager.Stub.Proxy代理执行PackageManager相关操作,IPackageManager.Stub.Proxy实际代理的是PackageManagerService。具体如下:
首先是IPackageManager是通过IPackageManager.aidl文件生成,同时生成了存根类IPackageManager.Stub,代理类:IPackageManager.Stub.Proxy
这个是packageManager进程通信的基本框架,然后PackageManagerService,它继承了IPackageManager.Stub,它作为PackageManager动作的实际执行者,在system_process中存在。 再是我们用户应用程序中的ApplicationPackageManager,先看它如何被获取的:
ContextImpl.java中有一个方法:
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
ApplicationPackageManager实际上是包装了一个IPackageManager对象(IPackageManager.Stub.Proxy),当我们调用queryIntentActivities时,实际通过代理对象去执行:
public List<ResolveInfo> queryIntentActivities(Intent intent,
int flags) {
try {
return mPM.queryIntentActivities(//mPM是IPackageManager.Stub.Proxy对象
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags);
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
}
经过进程通信,在PackageManagerService执行对应操作:
PackageManagerService的构建与获取
--PackageManagerService的构建:在system_process进程加载时,PackageManagerService被构建,在SystemServer.ServerThread.run中有如下一段代码,它就是加载 PackageManagerService的:
Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF);//启动PackageManagerService
///PackageManagerService///
public static final IPackageManager main(Context context, boolean factoryTest) {
PackageManagerService m = new PackageManagerService(context, factoryTest);
ServiceManager.addService("package", m);
return m;
}
--PackageManagerService获取:
先看前面在ContextImpl.java->getPackagerManager中:
IPackageManager pm = ActivityThread.getPackageManager();
/ActivityThread
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
从ServiceManager中获取的服务pakager,该服务在.PackageManagerService的构建时被注册到ServiceManager中的。
参考:
http://developer.android.com/reference/android/content/pm/PackageManager.html
http://blog.csdn.net/stonecao/article/details/6591454
http://www.open-open.com/lib/view/open1328776151311.html
http://www.linuxidc.com/Linux/2012-02/53072.htm
http://www.cnblogs.com/lee0oo0/archive/2012/08/08/2628458.html