Проблема с Aquery Android на Android 4.4 Kitkat

Я получаю проблему из-за библиотеки 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

Кажется, мне нужно минимизировать открытые файлы на внешнем хранилище, но как это сделать? Любая идея ???


person Nitin4Android    schedule 05.12.2013    source источник


Ответы (3)


Android Query выпускает другую версию (0.26.8) для решения этой проблемы: https://code.google.com/p/android-query/wiki/ReleaseNote#0.26.8

person Victor Pinto    schedule 28.02.2014

Изменить: я могу воспроизвести это, и, похоже, это происходит только на Kitkat. Предыдущие версии aquery также имеют эту проблему. Проверяем, что сейчас происходит.

Хорошо, я только что проверил это. Проблема в том, что мои настройки inPurgeable:

Почему я никогда НЕ должен использовать параметр BitmapFactory inPurgeable?

Это происходит, когда отображается слишком много изображений. Без опции у приложения не хватит памяти быстрее, чем лимит файла (так что это еще хуже).

Я предлагаю ограничить количество изображений в Activity или Fragments, которые все еще используются.

Я проверяю, есть ли лучшее решение, но, вероятно, это займет некоторое время.

Вы также можете попробовать другую библиотеку загрузки изображений и посмотреть, произойдет ли это.

person Peter Liu    schedule 05.12.2013
comment
Как только я нажимаю кнопку «Назад», приложение вылетает со следующими журналами: - person Nitin4Android; 05.12.2013
comment
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 - person Nitin4Android; 05.12.2013
comment
Как я могу ограничить количество изображений в Activity или Fragments, которые все еще используются? - person Nitin4Android; 05.12.2013
comment
Сколько изображений содержит ваше приложение? Этого не произойдет, пока у вас не будет 300-500 не выпущенных изображений ImageView (удерживаемых активностью или фрагментами, которые могут быть или не быть видимыми). - person Peter Liu; 06.12.2013
comment
Если отображается только небольшое количество изображений, существует вероятность утечки памяти или фрагментов. - person Peter Liu; 06.12.2013
comment
Я попытался оставить inPurgeable истинным и установить для inputShareable значение false. Кажется, все идет хорошо. - person nagoya0; 08.12.2013
comment
Спасибо, Петр, за заботу... +1 U :-) - person Nitin4Android; 10.12.2013

Я столкнулся с той же проблемой в KitKat. Исправление следующее: измените options.inInputShareable с «true» на «false» в BitmapAjaxCallback.java Каждое растровое изображение, загруженное с любого 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

person Starkom    schedule 05.02.2014