CountDownLatch与AIDL获取应用软件大小结合使用实例
2017-06-10 13:57
405 查看
最近做东西的时候,需要获取应用软件大小,看了很多人写的方法,大同小异。今天就参考别人的代码加一些自己的理解。整理一下,分享给大家。
下面是AIDL相关方法获取应用大小的例子,这个网上也有很多。
应用的场景:要采集多个app 的应用相关信息,其中包括应用大小,然后和其他软件信息(包名,应用名称,应用图标等信息)一起上报信息。
这中间就涉及到一个问题:如何保证分别采集多个应用的其他信息完成后再一起上传?因 为获取size的上述方法一次只能获取一个应用的大小,而且获取应用其他信息的方法和应用大小属于异步操作。软件大小是通过上述方法单独获取,其他信息是通过其他方法获取。多个软件信息都要获取完,最终再执行上传操作。
解决办法: 使用回调和CountDownLatch,就可以解决上述情景。
1.AIDL文件
![](https://oscdn.geek-share.com/Uploads/Images/Content/201706/e8282969c8517957e7ccfdb5d0251bef)
根据上图结构在src/main/aidl/android.content.pm/ 目录下添加IPackageStatsObserver.aidl 和 packageStats.aidl 2个文件。
下面是这2个文件的内容:
IPackageStatsObserver.aidl
packageStats.aidl
2.size大小获取
3.回调接口
4.CountDownLatch使用
至于对CountDownLatch使用的详细使用我就不详细讲述,网上有很多,如下链接可以参考:
http://www.importnew.com/15731.html
以上是内容主要是针对实际项目中用到的例子,结合网上关于获取软件大小的文章,做了一个综合性的演示。如果大家有什么问题,欢迎交流。
下面是AIDL相关方法获取应用大小的例子,这个网上也有很多。
应用的场景:要采集多个app 的应用相关信息,其中包括应用大小,然后和其他软件信息(包名,应用名称,应用图标等信息)一起上报信息。
这中间就涉及到一个问题:如何保证分别采集多个应用的其他信息完成后再一起上传?因 为获取size的上述方法一次只能获取一个应用的大小,而且获取应用其他信息的方法和应用大小属于异步操作。软件大小是通过上述方法单独获取,其他信息是通过其他方法获取。多个软件信息都要获取完,最终再执行上传操作。
解决办法: 使用回调和CountDownLatch,就可以解决上述情景。
1.AIDL文件
根据上图结构在src/main/aidl/android.content.pm/ 目录下添加IPackageStatsObserver.aidl 和 packageStats.aidl 2个文件。
下面是这2个文件的内容:
IPackageStatsObserver.aidl
package android.content.pm; import android.content.pm.PackageStats; oneway interface IPackageStatsObserver { void onGetStatsCompleted(in PackageStats pStats, boolean succeeded); }
packageStats.aidl
package android.content.pm; parcelable PackageStats;
2.size大小获取
public void queryPackageSize(CountDownLatch latch,IQueryPkgSizeCallback callBack, Context context, String pkgName) throws Exception{ if ( pkgName != null){ //使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfo PackageManager pm = context.getPackageManager(); //得到pm对象 try { //通过反射机制获得该隐藏函数 Method getPackageSizeInfo = pm.getClass().getMethod("getPackageSizeInfo", String.class,IPackageStatsObserver.class); //调用该函数,并且给其分配参数 ,待调用流程完成后会回调PkgSizeObserver类的函数 getPackageSizeInfo.invoke(pm, pkgName,new PkgSizeObserver(latch,callBack)); } catch(Exception ex){ Log.e(TAG, "NoSuchMethodException") ; ex.printStackTrace() ; throw ex ; // 抛出异常 } } }
//aidl文件形成的Bindler机制服务类 public class PkgSizeObserver extends IPackageStatsObserver.Stub{ private IQueryPkgSizeCallback callback; private CountDownLatch latch; PkgSizeObserver(CountDownLatch latch,IQueryPkgSizeCallback callback){ this.latch = latch; this.callback = callback; } /*** 回调函数, * @param pStats ,返回数据封装在PackageStats对象中 * @param succeeded 代表回调成功 */ @Override public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException { // TODO Auto-generated method stub Log.i(TAG,"PkgSizeObserver succeeded="+succeeded); if(succeeded){ cachesize = pStats.cacheSize ; //缓存大小n datasize = pStats.dataSize ; //数据大小 codesize = pStats.codeSize ; //应用程序大小 totalsize = cachesize + datasize + codesize ; Log.i(TAG, "cachesize--->"+cachesize+" datasize---->"+datasize+ " codeSize---->"+codesize); callback.queryPkgSize(true,totalsize); }else{ Log.i(TAG,"get size fail------>"); } latch.countDown();//每成功获取一个app的值,计数器减1,直到计数器为0时,不在阻塞,执行后续任务 } }
3.回调接口
public interface IQueryPkgSizeCallback{ void queryPkgSize(boolean isSucceed,long pkgTotalSize); }
4.CountDownLatch使用
CountDownLatch latch = new CountDownLatch(list.size);//要请求的多个app的list集合,计数器的大小为list的大小 if (list != null) { final ArrayList<对象名> apps = new ArrayList<>();//作为保存多个应用信息的list,最后返回的list for(final Iterator<对象名> iterator = list.iterator(); iterator.hasNext();) { final 对象名 info = iterator.next(); try { mModule.queryPackageSize(latch,new 类名.IQueryPkgSizeCallback() { @Override public void queryPkgSize(boolean isSucceed, long pkgTotalSize) { if(isSucceed){ Log.i(TAG,"getAllUserApp mAppInfoItem pkgName="+info.getAppPackage()+" system_flag="+info.getAppSystemFlag()+" app size="+mModule.formateFileSize(AEmmApplicaton.getContext(),pkgTotalSize)); info.setAppTotalSize(mModule.formateFileSize(AEmmApplicaton.getContext(),pkgTotalSize)); InstallApp.AppData app = new InstallApp.AppData(info.getAppPackage(), info.getAppName(), info.getAppFirstInstallTime(), info.getAppVersion(), info.getAppImageToString(), info.getAppSystemFlag(), info.getAppTotalSize()); apps.add(app);//每获取一个完整的应用信息,存入list里面 Log.i(TAG,"succ----->mLock.unlock()"); }else{ Log.i(TAG,"getAllUserApp queryPkgSize fail"); } } }, context,info.getAppPackage()); } catch (Exception e) { e.printStackTrace(); } } try { latch.await(); data = new InstallApp(apps);//计数器为0时,执行此处任务 Log.i(TAG, "----> latch.await()"+" app.size="+apps.size()); } catch (InterruptedException e) { e.printStackTrace(); }
至于对CountDownLatch使用的详细使用我就不详细讲述,网上有很多,如下链接可以参考:
http://www.importnew.com/15731.html
以上是内容主要是针对实际项目中用到的例子,结合网上关于获取软件大小的文章,做了一个综合性的演示。如果大家有什么问题,欢迎交流。
相关文章推荐
- Selenium2学习-031-WebUI自动化实战实例-029-JavaScript 在 Selenium 自动化中的应用实例之四(获取元素位置和大小)
- 使用VBA从海量Excel文件中模糊获取数据并生成新表(附实例) - (四) 结合病人病例,批量汇总实例
- Javascript 使用ajax与C#获取文件大小实例详解
- 闹钟实例与远程机制AIDL工具android:process=":remote"结合应用
- android -应用软件获取缓存大小和清除缓存功能
- 使用elecard stream软件获取编码码流每帧的大小
- 管道pipe与dup结合使用,应用实例
- 闹钟实例与远程机制AIDL工具android:process=":remote"结合应用
- Selenium2学习-022-WebUI自动化实战实例-020-JavaScript 在 Selenium 自动化中的应用实例之二(获取浏览器显示区域大小)
- 今日小作品:获取外部网IP软件(直接解压即可使用)
- 为 PHP 应用提速、提速、再提速!,第 1 部分: 使用操作码缓存软件提升性能和吞吐量
- 网络多出口应用中获取网通、电信、铁通IP地址实例(附2007年2月9日最新IP库) 推荐
- AJAX技术与asp.net 2.0的完美结合之Timer的web应用 及使用AJAX控件时的“Sys 未定义”错误解决办法
- SuperMap-AjaxMap应用1 使用TCPMap获取图形的所有坐标
- javascript 的高级应用 获取浏览器的信息:使用navigator对象
- 软件框架的利器、TangramMini组件应用教程三:基本使用
- 在vb中使用Iphlpapi.dll获取网络信息 第四章 第四节 实例二:探测到某个IP地址经过的路由列表
- 在vb中使用Iphlpapi.dll获取网络信息 第四章 第三节 实例一:网络数据流量图
- 需要使用单一实例合需要应用单例模式的区别
- JS&RE 控制图片显示大小, 弹出窗口自适应大小,自居中, 结合UBB与正则使用 By Stabx