4

由于 Aquery 库仅在滚动 GridView/ListView 加载带有分页的图像时才在 Android 4.4 Kitkat 上延迟加载图像,因此我遇到了一个问题。

以下是日志:

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

看来我需要最小化外部存储上的打开文件,但怎么做呢?任何想法 ???

4

3 回答 3

6

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

于 2014-02-28T18:24:07.310 回答
2

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

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

为什么我永远不会使用 BitmapFactory 的 inPurgeable 选项?

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

我的建议是限制 Activity 或 Fragments 中仍在使用的图像数量。

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

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

于 2013-12-05T09:09:27.210 回答
1

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

PS inInputShareable=false 与 inPurgeable=false 一样工作并导致快速 OOM :( AQuery 中的正确修复是将 BitmapFactory.decodeFileDescriptor 调用更改为 BitmapFactory.decodeByteArray(不要使用 decodeStream !!!它忽略了 inPurgeable 尽管它的 JavaDocs)

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

于 2014-02-05T21:49:07.737 回答