6

I'm using UIL (by Nosotra) to download images that the server renders, and it takes the server up to 50 seconds to create each image. The server's timeout is set to 15 seconds, so we've created a polling mechanism that is implemented in the ImageDownloader.getStream() method. After downloading, the images are displayed in a ViewPager (android.support.v4.view.ViewPager, just as the sample does.)

When users navigate to other pages, I wish to stop the polling without downloading files, but it seems there's no "nice" way to break the downloading flow.

getStream Pseudo-code

1. Parse custom-style URI ("asdf://mypng|123455678945643563245");
2. Make a real world URL from it.
3. Poll the server for the image url (causes the server to render - could take up to 1m30s).
4. Get the stream from the URL, return the stream to caller. 
       Example Code: InputStream is = (InputStream) url.getContent();

What's tried so far

Returning null from my getStream method causes an NullPointerException to be thrown, so it's basically same as just throwing an exception.

When an exception is thrown, the image does stop, but:

  1. A few images later, I get an OutOfMemoryError, so I show an error on screen. I shouldn't get the error. I already tried this SO question's checklist, but nothing worked. This is the OOM Stacktrace:OutOfMemoryError stacktrace nostra uil
  2. The downloading stops, and if the viewer won't recycle the view, when returning to that page, I'll still see that error page (no retry).

What I wish

I wish for me to have a "wait" method that would add stop the current download and re-add a new task to the end of the queue (currently on set on a QueueProcessingType.LIFO, and I wish it to download the re-added after after current pages, and any new pages the user wants should have precedence over the re-added ones).

I would also settle for avoiding the OutOfMemoryError.

Please help.

Community
  • 1
  • 1
Felix
  • 1,034
  • 1
  • 9
  • 29
  • 1
    See also [this issue](https://github.com/nostra13/Android-Universal-Image-Loader/issues/903) on the project's GitHub. – Felix Feb 04 '15 at 14:31
  • Are you sure your app doesn't have memory leaks? – nostra13 Feb 10 '15 at 13:56
  • Until now, we haven't noticed any, and the issue reproduces only when using the paged views. – Felix Feb 10 '15 at 14:10
  • @NOSTRA, I think that the memory leak / OOM is a side effect of us not really knowing how to stop / hold a download once its started. The difference between what most ppl would've done and us is that the images take a long time to render in the server, long enough for us to POLL the server for "tell me if an image is ready", and can't keep an open connection 'till then. So ho w can we stop an ImageDownloader once it's started, and can we abort that download and push it somehow back into the queue (LIFO/FIFO/MESS)? – Felix Feb 11 '15 at 11:46
  • 1
    What about `ImageLoader.cancelDisplayTask(...)`? – nostra13 Feb 11 '15 at 16:00
  • I think that it doesn't work if the `ImageDownloader` has already started (our implementation of it, `ReportPageDownloader` does the polling). I Voted you up because there's a good chance it will help many others. – Felix Feb 11 '15 at 16:18
  • I would like to see `ReportPageDownloader` sources. – nostra13 Feb 18 '15 at 14:00
  • I've sent it by email. In Short (and in pseudocode): `While (shouldKeepPolling){` `if (timeout) throw new Exception();` `if (pageIsReady) shouldKeepPolling = false; else WaitFourSeconds();` `} ` `DownloadPageImage();` Sorry linebreaks didn't work... – Felix Feb 19 '15 at 18:31
  • I hardly can help you. – nostra13 Feb 26 '15 at 19:10
  • Could you please share your getStream() method. Also Issue could be connected with viewPager. Which way to display on view pager do you use? Which method of UIL do you use - displayImage(), or loadImage(). Ther is difference between this two methods. Which min sdk do you use? About OOM, please read here https://developer.android.com/training/displaying-bitmaps/manage-memory.html – TAC Jun 08 '15 at 13:12
  • @TAC: I added Pseudo-Code to the question itself. I'm using a ViewPager, with an adapter, very similarly to what UIL does in the sample. I'm using `displayImage(uri, imageView, options, listener)`. Can you describe the difference? – Felix Jun 08 '15 at 13:41

1 Answers1

1

Problem could be here 4. Download the image, return the stream. Downloading - it is main feature of UIL. Just return the NetworkStream here. Also I had OOM on UIL with large Images and enabled MemoryCache. Also which image size do you have on server. in load Image method you have control on Size. Also so helpful UIL GitHub please read 3 and 4 paragraph.

TAC
  • 341
  • 1
  • 5
  • Sorry, I've probably threw you off, so I've edited the pseudocode better. I've read p3 and p4 on that github - the OOM is less important, I thought it was a side-effect of throwing an exception mid-getStream(). – Felix Jun 08 '15 at 14:34
  • 2
    I used to download images from AWS of Elastic Transcoder, so behaviour like your. i was returning null from getStream. It is still working. It has just warn by UIL logs. Also you could fing java doc on this method https://github.com/nostra13/Android-Universal-Image-Loader/blob/master/library/src/main/java/com/nostra13/universalimageloader/core/download/ImageDownloader.java throws IOException if some I/O error occurs during getting image stream throws UnsupportedOperationException if image URI has unsupported scheme(protocol) – TAC Jun 08 '15 at 14:51