Android Package Manager已经因TransactionTooLargeException而死亡

时间:2014-06-17 00:10:02

标签: android exception transactions android-package-managers

我的应用程序读取所有已安装的APK文件的列表,然后遍历列表以读取APK信息,但它会抛出TransactionTooLargeException异常。

根据我在此处阅读的http://developer.android.com/reference/android/os/TransactionTooLargeException.html,Google建议将大型交易分解为较小的交易。然而,似乎这种情况发生在循环浏览APK列表的中间。如果我抓住异常并继续它,其余的一切正常。有没有办法在调用getPackageInfo时减少内存使用量?即使它已经返回,该调用是否会保留一些内容。

这是发生时的痕迹:

at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:89)
at com.myapp.appreader.getAppDetails(Appreader.java:207)
at com.myapp.appreader.collectData(Appreader.java:99)
at com.myapp.appreader.AppDataCollectionTask.run(AppDataCollectionTask.java:26)
at com.myapp.appreader.service.AppDataTaskExecutor$AppDataAsyncTask.executeTask(AppDataTaskExecutor.java:439) 
at com.myapp.appreader.service.AppDataTaskExecutor$AppDataAsyncTask.doInBackground(AppDataTaskExecutor.java:327)
at com.myapp.appreader.service.AppDataTaskExecutor$AppDataAsyncTask.doInBackground(AppDataTaskExecutor.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)\nCaused by: android.os.TransactionTooLargeExceptionat android.os.BinderProxy.transact(Native Method)
at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:1538)
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:84)

2 个答案:

答案 0 :(得分:23)

Binder事务限制为1MB,这意味着大多数IPC调用的大小都必须适中。

如果在从TransactionTooLargeException检索数据时遇到PackageManager或类似的Binder失败(例如getPackageInfo()),请尝试通过多次调用将请求拆分,使用较少的标记(例如{ {1}})每次通话。希望这会减少任何单个交易的规模,使其低于1MB的限制。

此外,如果您使用GET_META_DATA上的调用返回多个结果(例如PackageManager,请尝试在该调用上请求 no 标志,然后检索每个包都是单独的,以避免一次性获得大量条目的大量数据。

当然,只使用你需要的标志,特别是如果你的电话可能包含一些标志。 getInstalledPackages()是一个典型的例子:许多应用使用它(例如,播放服务),但如果您不需要知道元数据信息,请不要请求它。

答案 1 :(得分:0)

我找到了解决此问题的方法,并发布了here

简而言之,它会找到已安装的应用程序' pacakges名称(使用ADB),然后一个接一个地获取有关每个名称的信息。