Android 包管理器因 TransactionTooLargeException 而死亡
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24253976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Package manager has died with TransactionTooLargeException
提问by Ray
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.
我的应用程序读取所有已安装 APK 文件的列表,然后遍历列表以读取 APK 信息,但是它会引发 TransactionTooLargeException 异常。
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.
从我在这里读到的http://developer.android.com/reference/android/os/TransactionTooLargeException.html,谷歌建议将大交易分解为小交易。然而,当循环遍历 APK 列表时,这似乎发生在中间。如果我捕获异常并继续它,其余的一切正常。有没有办法在调用 getPackageInfo 时减少内存使用量?即使在它已经返回之后,该调用是否仍然保留某些内容。
Here is the trace when it happened:
这是它发生时的踪迹:
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.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)
回答by CommonsWare
There is a 1MB limit on a Binder transaction, which means most IPC invocations have to be modest in size.
Binder 事务有 1MB 的限制,这意味着大多数 IPC 调用的大小必须适中。
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.
如果您TransactionTooLargeException
在从PackageManager
(例如getPackageInfo()
)检索数据时遇到或类似的 Binder 故障,请尝试将您的请求拆分为多个调用,GET_META_DATA
每个调用使用较少的标志(例如)。希望这会将任何单个事务的大小减少到 1MB 限制以下。
Also, if you are using calls on PackageManager
that return multiple results (e.g., getInstalledPackages()
, try asking for noflags 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.
此外,如果您正在使用PackageManager
返回多个结果的调用(例如,getInstalledPackages()
尝试在该调用上不要求任何标志,然后分别检索每个包的值,以避免一次获取大量条目的大量数据。
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.
而且,当然,只使用您需要的标志,特别是如果您的呼叫可能包含一些标志。GET_META_DATA
这是一个典型的例子:许多应用程序都使用它(例如,用于 Play 服务),但如果您不需要知道元数据信息,请不要请求它。