Aquery 在 Android 4.4 Kitkat 上的问题

4

我遇到了一个问题,因为当我在GridView/ListView上滚动并使用分页加载图片时,Aquery库在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

似乎我需要将外部存储中的打开文件最小化,但是该如何实现?有任何想法吗?
3个回答

6

2

编辑:

我能够重现它,而且似乎只会发生在Kitkat版本上。以前版本的aquery也有这个问题。现在正在检查发生了什么。

好的,我刚刚测试过了。问题是由于我的inPurgeable设置引起的:

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

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

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

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

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


一旦我按下返回按钮,应用程序就会崩溃,并显示以下日志: - Nitin4Android
12-05 17:44:19.808: E/InputChannel-JNI(1683): 错误24,复制通道fd 86。 12-05 17:44:19.818: E/InputEventSender(1683): 分发完成信号时出现异常。 12-05 17:44:19.818: E/MessageQueue-JNI(1683): MessageQueue回调中的异常:handleReceiveCallback。 - Nitin4Android
我如何限制仍在使用的Activity或Fragments中图像的数量? - Nitin4Android
你的应用程序中有多少张图片?除非你有300-500个ImageView没有被释放(由活动或片段持有,可能可见也可能不可见),否则这种情况不会发生。 - Peter Liu
感谢Peter的关心...给你点赞 :-) - Nitin4Android
显示剩余2条评论

1
我在安卓4.4版本中遇到了同样的问题。 解决方法如下:在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!!!即使其JavaDocs会忽略inPurgeable)
我发现这个问题与KitKat中的错误有关:https://code.google.com/p/android/issues/detail?id=65638

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接