Android 4.4 Kitkat上的Aquery Android问题

时间:2013-12-05 07:44:14

标签: android ioexception android-4.4-kitkat aquery

由于Aquery库在Android 4.4 Kitkat上延迟加载图像,只有在滚动浏览GridView / ListView加载图像时才会出现问题。

以下是日志:

12-03 10:39:43.678: W/AQuery(6261): reporting:java.io.IOException: open failed: EMFILE (Too many open files)
12-03 10:39:43.678: W/AQuery(6261): at java.io.File.createNewFile(File.java:946)
12-03 10:39:43.678: W/AQuery(6261): at com.androidquery.callback.AbstractAjaxCallback.getPreFile(AbstractAjaxCallback.java:1150)
12-03 10:39:43.678: W/AQuery(6261): at com.androidquery.callback.AbstractAjaxCallback.httpDo(AbstractAjaxCallback.java:1609)
12-03 10:39:43.678: W/AQuery(6261): at com.androidquery.callback.AbstractAjaxCallback.httpGet(AbstractAjaxCallback.java:1344)
12-03 10:39:43.678: W/AQuery(6261): at com.androidquery.callback.AbstractAjaxCallback.network(AbstractAjaxCallback.java:1243)
12-03 10:39:43.678: W/AQuery(6261): at com.androidquery.callback.AbstractAjaxCallback.networkWork(AbstractAjaxCallback.java:1082)
12-03 10:39:43.678: W/AQuery(6261): at com.androidquery.callback.AbstractAjaxCallback.backgroundWork(AbstractAjaxCallback.java:1014)
12-03 10:39:43.678: W/AQuery(6261): at com.androidquery.callback.AbstractAjaxCallback.run(AbstractAjaxCallback.java:977)
12-03 10:39:43.678: W/AQuery(6261): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
12-03 10:39:43.678: W/AQuery(6261): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
12-03 10:39:43.678: W/AQuery(6261): at java.lang.Thread.run(Thread.java:841)
12-03 10:39:43.678: W/AQuery(6261): Caused by: libcore.io.ErrnoException: open failed: EMFILE (Too many open files)
12-03 10:39:43.678: W/AQuery(6261): at libcore.io.Posix.open(Native Method)
12-03 10:39:43.678: W/AQuery(6261): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
12-03 10:39:43.678: W/AQuery(6261): at java.io.File.createNewFile(File.java:939)
12-03 10:39:43.678: W/AQuery(6261): ... 10 more

似乎我需要最小化外部存储上的打开文件但是如何做到这一点?任何想法???

3 个答案:

答案 0 :(得分:6)

Android Query发布另一个版本(0.26.8)来解决此问题: https://code.google.com/p/android-query/wiki/ReleaseNote#0.26.8

答案 1 :(得分:2)

编辑: 我可以重现它,它似乎只发生在Kitkat上。之前版本的aquery也有这个问题。检查现在发生了什么。

好的,我刚试过它。问题是导致我的inPurgeable设置:

Why would I ever NOT use BitmapFactory's inPurgeable option?

当显示的图像太多时会发生这种情况。如果没有该选项,应用程序将比文件限制更快地耗尽内存(所以情况更糟)。

我建议限制仍在使用的活动或碎片中的图像数量。

我正在检查是否有更好的解决方案,但可能需要一些时间。

您也可以尝试其他图像加载库,看看是否会发生这种情况。

答案 2 :(得分:1)

我在KitKat遇到了同样的问题。 修复如下:在BitmapAjaxCallback.java中将options.inInputShareable从'true'更改为'false' 从任何URL加载的每个位图都存储到文件中。如果inInputShareable为true,则您的进程具有重复的文件描述符以进行共享。因此,当> 1024个文件描述符泄露时,会发生EMFILE。 但实际上我无法理解为什么它在KitKat之前正常工作:)

<强> P.S。 inInputShareable = false作为inPurgeable = false并导致快速OOM :( AQuery中的正确修复是BitmapFactory.decodeFileDescriptor到BitmapFactory.decodeByteArray的更改调用(不要使用decodeStream !!!它忽略了inPurgeable,尽管它有JavaDocs)

我发现这个问题与KitKat中的错误有关:https://code.google.com/p/android/issues/detail?id=65638