Android 包管理器因 TransactionTooLargeException 而死亡 [英] Android Package manager has died with TransactionTooLargeException

查看:19
本文介绍了Android 包管理器因 TransactionTooLargeException 而死亡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My app reads the list of all installed APK files, and then loop through the list to read the APK info, however it throws a TransactionTooLargeException exception.

从我在这里读到的内容 http://developer.android.com/reference/android/os/TransactionTooLargeException.html,google 建议将大笔交易拆分为小笔交易.然而,当循环遍历 APK 列表时,这似乎发生在中间.如果我捕获异常并继续它,其余的一切正常.有没有办法在调用 getPackageInfo 时减少内存使用量?即使它已经返回,该调用是否仍保留某些内容.

From what I have read here http://developer.android.com/reference/android/os/TransactionTooLargeException.html, google recommends to break large transactions into smaller transactions. However it seems this happens in the middle when looping through the APK list. If I catch the exception and continue it, the rest all works fine. Is there a way to reduce the memory usage while calling the getPackageInfo? Does that call hold some thing even after it already returned.

这是它发生时的踪迹:

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)
Caused 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)

推荐答案

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

There is a 1MB limit on a Binder transaction, which means most IPC invocations have to be modest in size.

如果您在从 PackageManager(例如,getPackageInfo())检索数据时遇到 TransactionTooLargeException 或类似的 Binder 故障,请尝试拆分您的请求多次调用,每次调用使用较少的标志(例如,GET_META_DATA).希望这可以将任何单个交易的大小减少到 1MB 限制以下.

If you hit a TransactionTooLargeException or similar Binder failures when retrieving data from PackageManager (e.g., getPackageInfo()), try splitting your request over multiple calls, with fewer flags (e.g., GET_META_DATA) per call. Hopefully this will reduce the size of any individual transaction to be under the 1MB limit.

此外,如果您在 PackageManager 上使用返回多个结果的调用(例如,getInstalledPackages(),请尝试在调用,然后分别检索每个包的值,以避免一次获取大量条目的大量数据.

Also, if you are using calls on PackageManager that return multiple results (e.g., getInstalledPackages(), try asking for no flags on that call, then retrieving the values for each package individually, to avoid getting a lot of data on a lot of entries at once.

当然,只使用您需要的标志,特别是如果您的呼叫可能包含一些标志.GET_META_DATA 就是一个典型的例子:许多应用程序都使用它(例如,用于 Play 服务),但如果您不需要知道元数据信息,请不要请求它.

And, of course, only use flags that you need, particularly if your call might contain some. GET_META_DATA is a classic example of that: many apps use it (e.g., for Play Services), but if you do not need to know the metadata information, don't request it.

这篇关于Android 包管理器因 TransactionTooLargeException 而死亡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆