diff options
author | Sam Judd <judds@google.com> | 2014-06-28 11:05:23 -0700 |
---|---|---|
committer | Sam Judd <judds@google.com> | 2014-06-28 21:02:36 -0700 |
commit | 700284ec94a2c78a6157a31dea1d70d0de51b9f1 (patch) | |
tree | bd32953a7c8387d7eb14b860a8aa0001b960df99 /integration | |
parent | 0181060403cb0a7a2b344e4b2f55667194f09732 (diff) | |
download | glide-700284ec94a2c78a6157a31dea1d70d0de51b9f1.tar.gz |
Make Volley an optional dependency
Diffstat (limited to 'integration')
12 files changed, 833 insertions, 0 deletions
diff --git a/integration/pom.xml b/integration/pom.xml new file mode 100644 index 00000000..66241c2e --- /dev/null +++ b/integration/pom.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.github.bumptech.glide</groupId> + <artifactId>glide-parent</artifactId> + <version>3.3.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>glide-integration</artifactId> + <packaging>pom</packaging> + <name>Glide Integration</name> + + <modules> + <module>volley</module> + </modules> +</project> diff --git a/integration/volley/AndroidManifest.xml b/integration/volley/AndroidManifest.xml new file mode 100644 index 00000000..b644aab7 --- /dev/null +++ b/integration/volley/AndroidManifest.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.bumptech.glide.volley" + android:versionCode="1" + android:versionName="1.0.0" > + <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" /> + <application /> +</manifest> diff --git a/integration/volley/build.gradle b/integration/volley/build.gradle new file mode 100644 index 00000000..c8ab369f --- /dev/null +++ b/integration/volley/build.gradle @@ -0,0 +1,33 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:0.11.2' + } +} + +apply plugin: 'android-library' + +repositories { + mavenCentral() +} + +dependencies { + compile project(':library') + + compile 'com.mcxiaoke.volley:library:1.0.+' +} + +android { + compileSdkVersion 19 + buildToolsVersion = '19.1.0' + sourceSets { + main { + java.srcDirs = ['src/main/java'] + manifest.srcFile 'AndroidManifest.xml' + } + } +} + +apply from: "https://raw.githubusercontent.com/mcxiaoke/gradle-mvn-push/master/gradle-mvn-push.gradle" diff --git a/integration/volley/gradle.properties b/integration/volley/gradle.properties new file mode 100644 index 00000000..0f9e81b5 --- /dev/null +++ b/integration/volley/gradle.properties @@ -0,0 +1,6 @@ +POM_NAME=Glide Volley Integration +POM_ARTIFACT_ID=glide-volley-integration +POM_PACKAGING=aar +POM_LICENCE_NAME=The Apache Software License, Version 2.0 +POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt +POM_LICENCE_DIST=repo diff --git a/integration/volley/lint.xml b/integration/volley/lint.xml new file mode 100644 index 00000000..d9d6c9ff --- /dev/null +++ b/integration/volley/lint.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lint> + <issue id="AllowBackup" severity="ignore" /> +</lint> diff --git a/integration/volley/pom.xml b/integration/volley/pom.xml new file mode 100644 index 00000000..f1bf8725 --- /dev/null +++ b/integration/volley/pom.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.github.bumptech.glide</groupId> + <artifactId>glide-integration</artifactId> + <version>3.3.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>glide-volley-integration</artifactId> + <packaging>aar</packaging> + <name>Glide Volley Integration</name> + + <dependencies> + <dependency> + <groupId>com.github.bumptech.glide</groupId> + <artifactId>library</artifactId> + <version>3.3.0-SNAPSHOT</version> + <type>aar</type> + </dependency> + <dependency> + <groupId>com.mcxiaoke.volley</groupId> + <artifactId>library</artifactId> + <version>1.0.4</version> + </dependency> + </dependencies> + +</project> diff --git a/integration/volley/project.properties b/integration/volley/project.properties new file mode 100644 index 00000000..d226f51c --- /dev/null +++ b/integration/volley/project.properties @@ -0,0 +1,6 @@ +target=android-19 + +# https://code.google.com/p/android/issues/detail?id=40487 +renderscript.opt.level=O0 + +android.library=true diff --git a/integration/volley/src/main/java/com/bumptech/glide/volley/RequestQueueWrapper.java b/integration/volley/src/main/java/com/bumptech/glide/volley/RequestQueueWrapper.java new file mode 100644 index 00000000..b31f44b1 --- /dev/null +++ b/integration/volley/src/main/java/com/bumptech/glide/volley/RequestQueueWrapper.java @@ -0,0 +1,59 @@ +package com.bumptech.glide.volley; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.net.http.AndroidHttpClient; +import android.os.Build; +import com.android.volley.Cache; +import com.android.volley.Network; +import com.android.volley.RequestQueue; +import com.android.volley.toolbox.BasicNetwork; +import com.android.volley.toolbox.HttpClientStack; +import com.android.volley.toolbox.HttpStack; +import com.android.volley.toolbox.HurlStack; +import com.android.volley.toolbox.NoCache; +import com.android.volley.toolbox.Volley; +import com.bumptech.glide.load.engine.cache.DiskCache; + +import static android.content.pm.PackageManager.NameNotFoundException; + +/** + * A clone of the {@link Volley#newRequestQueue(Context)} allowing the user to set a disk cache and defaulting to + * no disk cache. + */ +public class RequestQueueWrapper { + + public static RequestQueue getRequestQueue(Context context) { + return getRequestQueue(context, new NoCache()); + } + + public static RequestQueue getRequestQueue(Context context, DiskCache diskCache) { + return getRequestQueue(context, new VolleyDiskCacheWrapper(diskCache)); + } + + public static RequestQueue getRequestQueue(Context context, Cache diskCache) { + String userAgent = "volley/0"; + try { + String packageName = context.getPackageName(); + PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); + userAgent = packageName + "/" + info.versionCode; + } catch (NameNotFoundException e) { + } + + final HttpStack stack; + if (Build.VERSION.SDK_INT >= 9) { + stack = new HurlStack(); + } else { + // Prior to Gingerbread, HttpUrlConnection was unreliable. + // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html + stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); + } + + Network network = new BasicNetwork(stack); + + + RequestQueue queue = new RequestQueue(diskCache, network); + queue.start(); + return queue; + } +} diff --git a/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyDiskCacheWrapper.java b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyDiskCacheWrapper.java new file mode 100644 index 00000000..6bc3dac2 --- /dev/null +++ b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyDiskCacheWrapper.java @@ -0,0 +1,337 @@ +package com.bumptech.glide.volley; + +import android.util.Log; +import com.android.volley.Cache; +import com.android.volley.toolbox.ByteArrayPool; +import com.android.volley.toolbox.DiskBasedCache; +import com.android.volley.toolbox.PoolingByteArrayOutputStream; +import com.bumptech.glide.load.engine.cache.StringKey; +import com.bumptech.glide.load.engine.cache.DiskCache; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Closely based on {@link DiskBasedCache}. + */ +public class VolleyDiskCacheWrapper implements Cache { + private static final String TAG = "VolleyDiskCacheWrapper"; + /** Magic number for current version of cache file format. */ + private static final int CACHE_MAGIC = 0x20120504; + // 2 mb. + private static final int BYTE_POOL_SIZE = 2 * 1024 * 1024; + // 8 kb. + private static final int DEFAULT_BYTE_ARRAY_SIZE = 8 * 1024; + + private final DiskCache diskCache; + private final ByteArrayPool byteArrayPool; + + public VolleyDiskCacheWrapper(DiskCache diskCache) { + this.diskCache = diskCache; + this.byteArrayPool = new ByteArrayPool(BYTE_POOL_SIZE); + } + + @Override + public Entry get(String key) { + InputStream result = diskCache.get(new StringKey(key)); + if (result == null) { + return null; + } + try { + CacheHeader header = readHeader(result); + byte[] data = streamToBytes(result); + return header.toCacheEntry(data); + } catch (IOException e) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + e.printStackTrace(); + } + diskCache.delete(new StringKey(key)); + } finally { + try { + result.close(); + } catch (IOException e) { } + } + return null; + } + + @Override + public void put(final String key, final Entry entry) { + diskCache.put(new StringKey(key), new DiskCache.Writer() { + @Override + public boolean write(OutputStream os) { + CacheHeader header = new CacheHeader(key, entry); + boolean success = header.writeHeader(os); + if (success) { + try { + os.write(entry.data); + } catch (IOException e) { + success = false; + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Unable to write data", e); + } + } + } + return success; + } + }); + } + + @Override + public void initialize() { } + + @Override + public void invalidate(String key, boolean fullExpire) { + Entry entry = get(key); + if (entry != null) { + entry.softTtl = 0; + if (fullExpire) { + entry.ttl = 0; + } + put(key, entry); + } + } + + @Override + public void remove(String key) { + diskCache.delete(new StringKey(key)); + } + + @Override + public void clear() { } + + /** + * Reads the header off of an InputStream and returns a CacheHeader object. + * @param is The InputStream to read from. + * @throws IOException + */ + public CacheHeader readHeader(InputStream is) throws IOException { + CacheHeader entry = new CacheHeader(); + int magic = readInt(is); + if (magic != CACHE_MAGIC) { + // don't bother deleting, it'll get pruned eventually + throw new IOException(); + } + entry.key = readString(is); + entry.etag = readString(is); + if (entry.etag.equals("")) { + entry.etag = null; + } + entry.serverDate = readLong(is); + entry.ttl = readLong(is); + entry.softTtl = readLong(is); + entry.responseHeaders = readStringStringMap(is); + return entry; + } + + /** + * Handles holding onto the cache headers for an entry. + */ + // Visible for testing. + class CacheHeader { + /** The size of the data identified by this CacheHeader. (This is not + * serialized to disk. */ + public long size; + + /** The key that identifies the cache entry. */ + public String key; + + /** ETag for cache coherence. */ + public String etag; + + /** Date of this response as reported by the server. */ + public long serverDate; + + /** TTL for this record. */ + public long ttl; + + /** Soft TTL for this record. */ + public long softTtl; + + /** Headers from the response resulting in this cache entry. */ + public Map<String, String> responseHeaders; + + private CacheHeader() { } + + /** + * Instantiates a new CacheHeader object + * @param key The key that identifies the cache entry + * @param entry The cache entry. + */ + public CacheHeader(String key, Entry entry) { + this.key = key; + this.size = entry.data.length; + this.etag = entry.etag; + this.serverDate = entry.serverDate; + this.ttl = entry.ttl; + this.softTtl = entry.softTtl; + this.responseHeaders = entry.responseHeaders; + } + + /** + * Creates a cache entry for the specified data. + */ + public Entry toCacheEntry(byte[] data) { + Entry e = new Entry(); + e.data = data; + e.etag = etag; + e.serverDate = serverDate; + e.ttl = ttl; + e.softTtl = softTtl; + e.responseHeaders = responseHeaders; + return e; + } + + /** + * Writes the contents of this CacheHeader to the specified OutputStream. + */ + public boolean writeHeader(OutputStream os) { + try { + writeInt(os, CACHE_MAGIC); + writeString(os, key); + writeString(os, etag == null ? "" : etag); + writeLong(os, serverDate); + writeLong(os, ttl); + writeLong(os, softTtl); + writeStringStringMap(responseHeaders, os); + os.flush(); + return true; + } catch (IOException e) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d("%s", e.toString()); + } + return false; + } + } + } + + /* + * Homebrewed simple serialization system used for reading and writing cache + * headers on disk. Once upon a time, this used the standard Java + * Object{Input,Output}Stream, but the default implementation relies heavily + * on reflection (even for standard types) and generates a ton of garbage. + */ + + /** + * Simple wrapper around {@link InputStream#read()} that throws EOFException + * instead of returning -1. + */ + private static int read(InputStream is) throws IOException { + int b = is.read(); + if (b == -1) { + throw new EOFException(); + } + return b; + } + + static void writeInt(OutputStream os, int n) throws IOException { + os.write((n >> 0) & 0xff); + os.write((n >> 8) & 0xff); + os.write((n >> 16) & 0xff); + os.write((n >> 24) & 0xff); + } + + static int readInt(InputStream is) throws IOException { + int n = 0; + n |= (read(is) << 0); + n |= (read(is) << 8); + n |= (read(is) << 16); + n |= (read(is) << 24); + return n; + } + + static void writeLong(OutputStream os, long n) throws IOException { + os.write((byte)(n >>> 0)); + os.write((byte)(n >>> 8)); + os.write((byte)(n >>> 16)); + os.write((byte)(n >>> 24)); + os.write((byte)(n >>> 32)); + os.write((byte)(n >>> 40)); + os.write((byte)(n >>> 48)); + os.write((byte)(n >>> 56)); + } + + static long readLong(InputStream is) throws IOException { + long n = 0; + n |= ((read(is) & 0xFFL) << 0); + n |= ((read(is) & 0xFFL) << 8); + n |= ((read(is) & 0xFFL) << 16); + n |= ((read(is) & 0xFFL) << 24); + n |= ((read(is) & 0xFFL) << 32); + n |= ((read(is) & 0xFFL) << 40); + n |= ((read(is) & 0xFFL) << 48); + n |= ((read(is) & 0xFFL) << 56); + return n; + } + + static void writeString(OutputStream os, String s) throws IOException { + byte[] b = s.getBytes("UTF-8"); + writeLong(os, b.length); + os.write(b, 0, b.length); + } + + String readString(InputStream is) throws IOException { + int n = (int) readLong(is); + byte[] b = streamToBytes(is, n, byteArrayPool.getBuf(n)); + String result = new String(b, "UTF-8"); + byteArrayPool.returnBuf(b); + return result; + } + + static void writeStringStringMap(Map<String, String> map, OutputStream os) throws IOException { + if (map != null) { + writeInt(os, map.size()); + for (Map.Entry<String, String> entry : map.entrySet()) { + writeString(os, entry.getKey()); + writeString(os, entry.getValue()); + } + } else { + writeInt(os, 0); + } + } + + Map<String, String> readStringStringMap(InputStream is) throws IOException { + int size = readInt(is); + Map<String, String> result = (size == 0) + ? Collections.<String, String>emptyMap() + : new HashMap<String, String>(size); + for (int i = 0; i < size; i++) { + String key = readString(is).intern(); + String value = readString(is).intern(); + result.put(key, value); + } + return result; + } + + /** + * Reads the contents of an InputStream into a byte[]. + */ + private static byte[] streamToBytes(InputStream in, int length, byte[] bytes) throws IOException { + int count; + int pos = 0; + while (pos < length && ((count = in.read(bytes, pos, length - pos)) != -1)) { + pos += count; + } + if (pos != length) { + throw new IOException("Expected " + length + " bytes, read " + pos + " bytes"); + } + return bytes; + } + + private byte[] streamToBytes(InputStream in) throws IOException { + PoolingByteArrayOutputStream outputStream = new PoolingByteArrayOutputStream(byteArrayPool); + byte[] bytes = byteArrayPool.getBuf(DEFAULT_BYTE_ARRAY_SIZE); + int pos = 0; + while ((in.read(bytes, pos, bytes.length - pos)) != -1) { + outputStream.write(bytes); + } + byteArrayPool.returnBuf(bytes); + byte[] result = outputStream.toByteArray(); + outputStream.close(); + return result; + } +} diff --git a/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyRequestFuture.java b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyRequestFuture.java new file mode 100644 index 00000000..460364bb --- /dev/null +++ b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyRequestFuture.java @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bumptech.glide.volley; + +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.VolleyError; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * TODO: contribute cancel modifications to volley and remove this class. + * + * A Future that represents a Volley request. + * + * Used by providing as your response and error listeners. For example: + * <pre> + * RequestFuture<JSONObject> future = RequestFuture.newFuture(); + * MyRequest request = new MyRequest(URL, future, future); + * + * // If you want to be able to cancel the request: + * future.setRequest(requestQueue.add(request)); + * + * // Otherwise: + * requestQueue.add(request); + * + * try { + * JSONObject response = future.get(); + * // do something with response + * } catch (InterruptedException e) { + * // handle the error + * } catch (ExecutionException e) { + * // handle the error + * } + * </pre> + * + * @param <T> The type of parsed response this future expects. + */ +public class VolleyRequestFuture<T> implements Future<T>, Response.Listener<T>, + Response.ErrorListener { + private Request<?> mRequest; + private boolean mResultReceived = false; + private T mResult; + private VolleyError mException; + private boolean mIsCancelled = false; + + public static <E> VolleyRequestFuture<E> newFuture() { + return new VolleyRequestFuture<E>(); + } + + public VolleyRequestFuture() {} + + public synchronized void setRequest(Request<?> request) { + mRequest = request; + if (mIsCancelled && mRequest != null) { + mRequest.cancel(); + } + } + + @Override + public synchronized boolean cancel(boolean mayInterruptIfRunning) { + if (isDone()) { + return false; + } + mIsCancelled = true; + if (mRequest != null) { + mRequest.cancel(); + } + notifyAll(); + + return true; + } + + @Override + public T get() throws InterruptedException, ExecutionException { + try { + return doGet(null); + } catch (TimeoutException e) { + throw new AssertionError(e); + } + } + + @Override + public T get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return doGet(TimeUnit.MILLISECONDS.convert(timeout, unit)); + } + + private synchronized T doGet(Long timeoutMs) + throws InterruptedException, ExecutionException, TimeoutException { + if (mException != null) { + throw new ExecutionException(mException); + } + + if (mResultReceived) { + return mResult; + } + + if (isCancelled()) { + throw new CancellationException(); + } + + if (timeoutMs == null) { + wait(0); + } else if (timeoutMs > 0) { + wait(timeoutMs); + } + + if (mException != null) { + throw new ExecutionException(mException); + } + + if (isCancelled()) { + throw new CancellationException(); + } + + if (!mResultReceived) { + throw new TimeoutException(); + } + + return mResult; + } + + @Override + public boolean isCancelled() { + return mIsCancelled; + } + + @Override + public synchronized boolean isDone() { + return mResultReceived || mException != null || isCancelled(); + } + + @Override + public synchronized void onResponse(T response) { + mResultReceived = true; + mResult = response; + notifyAll(); + } + + @Override + public synchronized void onErrorResponse(VolleyError error) { + mException = error; + notifyAll(); + } +} + diff --git a/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyStreamFetcher.java b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyStreamFetcher.java new file mode 100644 index 00000000..76e2bbcc --- /dev/null +++ b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyStreamFetcher.java @@ -0,0 +1,102 @@ +package com.bumptech.glide.volley; + +import com.android.volley.NetworkResponse; +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.Response; +import com.android.volley.toolbox.HttpHeaderParser; +import com.bumptech.glide.Priority; +import com.bumptech.glide.load.data.DataFetcher; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/** + * A DataFetcher backed by volley for fetching images via http. + */ +public class VolleyStreamFetcher implements DataFetcher<InputStream> { + private final RequestQueue requestQueue; + private final String url; + private VolleyRequestFuture<InputStream> requestFuture; + + @SuppressWarnings("unused") + public VolleyStreamFetcher(RequestQueue requestQueue, String url) { + this(requestQueue, url, null); + } + + public VolleyStreamFetcher(RequestQueue requestQueue, String url, VolleyRequestFuture<InputStream> requestFuture) { + this.requestQueue = requestQueue; + this.url = url; + this.requestFuture = requestFuture; + if (requestFuture == null) { + this.requestFuture = VolleyRequestFuture.newFuture(); + } + } + + @Override + public InputStream loadData(Priority priority) throws Exception { + GlideRequest request = new GlideRequest(url, requestFuture, glideToVolleyPriority(priority)); + + requestFuture.setRequest(requestQueue.add(request)); + + return requestFuture.get(); + } + + @Override + public void cleanup() { + // Do nothing. + } + + @Override + public String getId() { + return url; + } + + @Override + public void cancel() { + VolleyRequestFuture<InputStream> localFuture = requestFuture; + if (localFuture != null) { + localFuture.cancel(true); + } + } + + private static Request.Priority glideToVolleyPriority(Priority priority) { + switch (priority) { + case LOW: + return Request.Priority.LOW; + case HIGH: + return Request.Priority.HIGH; + case IMMEDIATE: + return Request.Priority.IMMEDIATE; + default: + return Request.Priority.NORMAL; + + } + } + + private static class GlideRequest extends Request<byte[]> { + private final VolleyRequestFuture<InputStream> future; + private Priority priority; + + public GlideRequest(String url, VolleyRequestFuture<InputStream> future, Priority priority) { + super(Method.GET, url, future); + this.future = future; + this.priority = priority; + } + + @Override + public Priority getPriority() { + return priority; + } + + @Override + protected Response<byte[]> parseNetworkResponse(NetworkResponse response) { + return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response)); + } + + @Override + protected void deliverResponse(byte[] response) { + future.onResponse(new ByteArrayInputStream(response)); + } + } +} diff --git a/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyUrlLoader.java b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyUrlLoader.java new file mode 100644 index 00000000..43705a65 --- /dev/null +++ b/integration/volley/src/main/java/com/bumptech/glide/volley/VolleyUrlLoader.java @@ -0,0 +1,64 @@ +package com.bumptech.glide.volley; + +import android.content.Context; +import com.android.volley.RequestQueue; +import com.bumptech.glide.load.model.GenericLoaderFactory; +import com.bumptech.glide.load.model.GlideUrl; +import com.bumptech.glide.load.model.ModelLoader; +import com.bumptech.glide.load.model.ModelLoaderFactory; +import com.bumptech.glide.load.data.DataFetcher; + +import java.io.InputStream; + +/** + * A simple model loader for fetching images for a given url + */ +public class VolleyUrlLoader implements ModelLoader<GlideUrl, InputStream> { + + public interface FutureFactory { + public VolleyRequestFuture<InputStream> build(); + } + + public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> { + private final FutureFactory futureFactory; + private RequestQueue requestQueue; + + public Factory(RequestQueue requestQueue) { + this(requestQueue, new DefaultFutureFactory()); + } + + public Factory(RequestQueue requestQueue, FutureFactory futureFactory) { + this.requestQueue = requestQueue; + this.futureFactory = futureFactory; + } + + @Override + public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) { + return new VolleyUrlLoader(requestQueue, futureFactory); + } + + @Override + public void teardown() { } + } + + private final RequestQueue requestQueue; + private final FutureFactory futureFactory; + + public VolleyUrlLoader(RequestQueue requestQueue, FutureFactory futureFactory) { + this.requestQueue = requestQueue; + this.futureFactory = futureFactory; + } + + @Override + public DataFetcher<InputStream> getResourceFetcher(GlideUrl url, int width, int height) { + return new VolleyStreamFetcher(requestQueue, url.toString(), futureFactory.build()); + } + + private static class DefaultFutureFactory implements FutureFactory { + @Override + public VolleyRequestFuture<InputStream> build() { + return VolleyRequestFuture.newFuture(); + } + } + +} |