Aquery Android Issue on Android 4.4 Kitkat

2k views Asked by At

I a getting an issue due to Aquery library for lazy loading of images on Android 4.4 Kitkat only when scrolling through the GridView/ListView loading images with pagination.

Following are the logs:

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

It seems I need to Minimize Open Files on External Storage but how to do it? Any idea ???

3

There are 3 answers

7
Peter Liu On

Edit: I can reproduce it, and it seems to happen on Kitkat only. Previously versions of aquery also have this issue. Checking what's going on now.

Ok I just tested it. The issue is cause my inPurgeable settings:

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

It will happen when there are too many images displayed. Without the option, app will run out of memory quicker than the file limit (so it's even worse).

What I suggest is limit the number of images in Activity or Fragments that is still in use.

I am checking if there's a better solution, but will likely take some time.

You might also try other image loading library and see if that happens.

0
Starkom On

I met the same problem in KitKat. Fix is following: change options.inInputShareable from 'true' to 'false' in BitmapAjaxCallback.java Every bitmap loaded from any URL is stored to file. And if inInputShareable is true, your process has duplicated file descriptor for sharing. So when >1024 file descriptors are leaked, EMFILE is occured. But actually I can't understand why it worked correctly before KitKat :)

P.S. inInputShareable=false works as inPurgeable=false and leads to rapid OOM :( Correct fix in AQuery is change call of BitmapFactory.decodeFileDescriptor to BitmapFactory.decodeByteArray (Don't use decodeStream!!! It ignores inPurgeable despite its JavaDocs)

And I've found that the issue is related with bug in KitKat: https://code.google.com/p/android/issues/detail?id=65638

0
Victor Pinto On

Android Query release another version (0.26.8) to solve this problem: https://code.google.com/p/android-query/wiki/ReleaseNote#0.26.8