diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2014-01-12 16:15:29 +0100 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2014-01-12 23:21:55 +0100 |
| commit | 7fe17b6b441e145e7e4c46f0aed83b86a00d4e57 (patch) | |
| tree | 29136ac2e174221f8ab65bb4e7874e6a2de6f1f2 /main/src/cgeo/geocaching/network | |
| parent | df177f0e15f4a8fa3dd378648477200596306be9 (diff) | |
| download | cgeo-7fe17b6b441e145e7e4c46f0aed83b86a00d4e57.zip cgeo-7fe17b6b441e145e7e4c46f0aed83b86a00d4e57.tar.gz cgeo-7fe17b6b441e145e7e4c46f0aed83b86a00d4e57.tar.bz2 | |
When storing a cache, download images concurrently
Up to 5 downloads can happen simultaneously. Also, those downloads are
executed concurrently to static map requests if any.
Diffstat (limited to 'main/src/cgeo/geocaching/network')
| -rw-r--r-- | main/src/cgeo/geocaching/network/HtmlImage.java | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/network/HtmlImage.java b/main/src/cgeo/geocaching/network/HtmlImage.java index 1f50bd7..774dbf6 100644 --- a/main/src/cgeo/geocaching/network/HtmlImage.java +++ b/main/src/cgeo/geocaching/network/HtmlImage.java @@ -6,6 +6,7 @@ import cgeo.geocaching.compatibility.Compatibility; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.files.LocalStorage; import cgeo.geocaching.list.StoredList; +import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.FileUtils; import cgeo.geocaching.utils.ImageUtils; import cgeo.geocaching.utils.Log; @@ -15,6 +16,16 @@ import ch.boye.httpclientandroidlib.androidextra.Base64; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.Nullable; +import rx.Observable; +import rx.Observable.OnSubscribeFunc; +import rx.Observer; +import rx.Scheduler; +import rx.Subscription; +import rx.concurrency.Schedulers; +import rx.subjects.PublishSubject; +import rx.subscriptions.CompositeSubscription; +import rx.subscriptions.Subscriptions; +import rx.util.functions.Func1; import android.content.res.Resources; import android.graphics.Bitmap; @@ -32,6 +43,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class HtmlImage implements Html.ImageGetter { @@ -65,6 +81,14 @@ public class HtmlImage implements Html.ImageGetter { final private int maxHeight; final private Resources resources; + // Background loading + final private PublishSubject<Observable<String>> loading = PublishSubject.create(); + final Observable<String> waitForEnd = Observable.merge(loading).publish().refCount(); + final CompositeSubscription subscription = new CompositeSubscription(waitForEnd.subscribe()); + final private Scheduler downloadScheduler = Schedulers.executor(new ThreadPoolExecutor(5, 5, 5, TimeUnit.SECONDS, + new LinkedBlockingQueue<Runnable>())); + final private Set<String> downloading = new HashSet<String>(); + public HtmlImage(final String geocode, final boolean returnErrorImage, final int listId, final boolean onlySave) { this.geocode = geocode; this.returnErrorImage = returnErrorImage; @@ -84,6 +108,46 @@ public class HtmlImage implements Html.ImageGetter { @Nullable @Override public BitmapDrawable getDrawable(final String url) { + if (!onlySave) { + return loadDrawable(url); + } else { + synchronized(downloading) { + if (!downloading.contains(url)) { + loading.onNext(fetchDrawable(url).map(new Func1<BitmapDrawable, String>() { + @Override + public String call(final BitmapDrawable bitmapDrawable) { + return url; + } + })); + downloading.add(url); + } + return null; + } + } + } + + public Observable<BitmapDrawable> fetchDrawable(final String url) { + return Observable.create(new OnSubscribeFunc<BitmapDrawable>() { + @Override + public Subscription onSubscribe(final Observer<? super BitmapDrawable> observer) { + if (!subscription.isUnsubscribed()) { + observer.onNext(loadDrawable(url)); + } + observer.onCompleted(); + return Subscriptions.empty(); + } + }).subscribeOn(downloadScheduler); + } + + public void waitForBackgroundLoading(@Nullable final CancellableHandler handler) { + if (handler != null) { + handler.unsubscribeIfCancelled(subscription); + } + loading.onCompleted(); + waitForEnd.toBlockingObservable().lastOrDefault(null); + } + + private BitmapDrawable loadDrawable(final String url) { // Reject empty and counter images URL if (StringUtils.isBlank(url) || isCounter(url)) { return getTransparent1x1Image(resources); |
