您的位置:首页 > 大数据 > 人工智能

CountDownLatch与AIDL获取应用软件大小结合使用实例

2017-06-10 13:57 405 查看
最近做东西的时候,需要获取应用软件大小,看了很多人写的方法,大同小异。今天就参考别人的代码加一些自己的理解。整理一下,分享给大家。

下面是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

以上是内容主要是针对实际项目中用到的例子,结合网上关于获取软件大小的文章,做了一个综合性的演示。如果大家有什么问题,欢迎交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐