【问题标题】:Aquery Android Issue on Android 4.4 KitkatAndroid 4.4 Kitkat 上的 Aquery Android 问题
【发布时间】:2013-12-05 07:44:14
【问题描述】:

我遇到了一个问题,因为 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

似乎我需要最小化外部存储上的打开文件,但该怎么做?有什么想法???

【问题讨论】:

    标签: android ioexception android-4.4-kitkat aquery


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      您也可以尝试其他图片加载库,看看是否会出现这种情况。

      【讨论】:

      • 当我按下返回按钮时,应用程序崩溃并显示以下日志:
      • 12-05 17:44:19.808:E/InputChannel-JNI(1683):错误 24 dup 通道 fd 86。12-05 17:44:19.818:E/InputEventSender(1683):异常发送完成信号。 12-05 17:44:19.818:E/MessageQueue-JNI(1683):MessageQueue 回调中的异常:handleReceiveCallback
      • 如何限制 Activity 或 Fragments 中仍在使用的图像数量..?
      • 您的应用保存了多少张图片?直到您有 300-500 个未释放的 ImageView(由可能可见或不可见的 Activity 或 Fragment 保留)时,才会发生这种情况。
      • 如果只显示少量图像,则可能存在内存泄漏活动或碎片。
      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多