您现在的位置是:首页 > 文章详情

[Android Pro] PackageManager#getPackageSizeInfo (hide)

日期:2017-06-30点击:271

referce to : http://www.baidufe.com/item/8786bc2e95a042320bef.html

计算Android App所占用d的手机内存(RAM)大小、App所产生的数据(Data)大小、App本身所占用的磁盘空间(ROM)大小。当然,这个就必须用到PackageManager了。

1、查看Android中PackageManager源码,找到getPackageSizeInfo方法:

 

复制代码
/** * Retrieve the size information for a package. * Since this may take a little while, the result will * be posted back to the given observer. The calling context * should have the {@link android.Manifest.permission#GET_PACKAGE_SIZE} permission. * * @param packageName The name of the package whose size information is to be retrieved * @param observer An observer callback to get notified when the operation * is complete. * {@link android.content.pm.IPackageStatsObserver#onGetStatsCompleted(PackageStats, boolean)} * The observer's callback is invoked with a PackageStats object(containing the * code, data and cache sizes of the package) and a boolean value representing * the status of the operation. observer may be null to indicate that * no callback is desired. * * @hide */ public abstract void getPackageSizeInfo(String packageName, IPackageStatsObserver observer);
复制代码

 

2、getPackageSizeInfo方法有两个参数,第一个是需要计算的App包名,第二个是一个回调。不过IPackageStatesObserver这个class在API里貌似找不到,找了点儿资料,需要通过Android AIDL的方式来搞。方法:

1)、在src目录下新建android.content.pm包

2)、在该包下新建PackageStats.aidl文件,内容如下:

package android.content.pm; parcelable PackageStats;

      3)、在该包下新建IPackageStatsObserver.aidl接口文件,内容如下:

复制代码
package android.content.pm; import android.content.pm.PackageStats; /** * API for package data change related callbacks from the Package Manager. * Some usage scenarios include deletion of cache directory, generate * statistics related to code, data, cache usage(TODO) * {@hide} */ oneway interface IPackageStatsObserver { void onGetStatsCompleted(in PackageStats pStats, boolean succeeded); }
复制代码

 3、getPackageSizeInfo方法不能通过context.getPackageManager.getPackageSizeInfo的方式来调用,因为它其实是一个invoke受限的方法,所以必须通过反射实现:

复制代码
/** * 获取Android Native App的缓存大小、数据大小、应用程序大小 * * @param context * Context对象 * @param pkgName * 需要检测的Native App包名 * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalAccessException */ public static void getPkgSize(final Context context, String pkgName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { // getPackageSizeInfo是PackageManager中的一个private方法,所以需要通过反射的机制来调用 Method method = PackageManager.class.getMethod("getPackageSizeInfo", new Class[] { String.class, IPackageStatsObserver.class }); // 调用 getPackageSizeInfo 方法,需要两个参数:1、需要检测的应用包名;2、回调 method.invoke(context.getPackageManager(), new Object[] { pkgName, new IPackageStatsObserver.Stub() { @Override public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException { // 子线程中默认无法处理消息循环,自然也就不能显示Toast,所以需要手动Looper一下  Looper.prepare(); // 从pStats中提取各个所需数据  Toast.makeText(context, "缓存大小=" + Formatter.formatFileSize(context, pStats.cacheSize) + "\n数据大小=" + Formatter.formatFileSize(context, pStats.dataSize) + "\n程序大小=" + Formatter.formatFileSize(context, pStats.codeSize), Toast.LENGTH_LONG).show(); // 遍历一次消息队列,弹出Toast  Looper.loop(); } } }); }
复制代码

我是直接在Observer回调中通过Toast的方式直接显示出来的,不过这个回调是在子线 程中异步完成的,子线程中默认不处理消息循环,所以Toast.show无法被正确执行,需要手动将Toast显示部分的内容,加到Looper中,分别 调用Looper.prepare和Looper.loop方法即可!

4、当然,根据PackageManager中getPackageSizeInfo注释中的提示,还需要在AndroidManifest.xml中加入permission:

<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"></uses-permission>

 

 

分类:  Android Pro
本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/p/4673403.html如需转载请自行联系原作者

demoblog
原文链接:https://yq.aliyun.com/articles/363577
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章