提交 700284ec 编写于 作者: S Sam Judd

Make Volley an optional dependency

上级 01810604
......@@ -20,6 +20,8 @@ samples/flickr/out
samples/flickr/bin
samples/flickr/local.properties
samples/flickr/target
integration/volley/target/**
**/local.properties
*.keystore
**/.idea/*
.settings
......
Glide
=====
Glide is fast and efficient image loading library for Android that wraps image downloading, resizing, memory and disk caching, and bitmap recycling into one simple and easy to use interface. By default, Glide includes an implementation for fetching images over http based on Google's Volley project for fast, parallelized network operations on Android.
Glide is fast and efficient image loading library for Android that wraps image downloading, resizing, memory and disk
caching, and bitmap recycling into one simple and easy to use interface. Glide includes a flexible api allowing it to
plug in to almost any network stack. By default Glide uses a custom HttpUrlConnection based stack, but also includes a
utility library to plug in to Google's Volley project instead.
Glide's primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image.
Glide's primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is
also effective for almost any case where you need to fetch, resize, and display a remote image.
Download
--------
You can download a jar from GitHub's [release page](https://github.com/bumptech/glide/releases) or to use the 3.0 alpha branch, use Gradle:
You can download a jar from GitHub's [release page](https://github.com/bumptech/glide/releases) or to use the 3.0 alpha
branch, use Gradle:
```groovy
repositories {
......@@ -38,12 +43,41 @@ In your module:
```xml
<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide</artifactId>
<artifactId>library</artifactId>
<version>3.3.0-SNAPSHOT</version>
<type>aar</type>
</dependency>
```
Volley
-------
Volley is now an optional dependency that can be included via a utility library. More utility libraries for other
projects will hopefully be coming soon. To use the utility library with Gradle, add:
```groovy
dependencies {
compile group: 'com.github.bumptech.glide', name:'volley', version:'3.3.0-SNAPSHOT', changing:true
compile 'com.mcxiaoke.volley:library:1.0.+'
}
```
Or with maven:
```xml
<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>volley</artifactId>
<version>3.3.0-SNAPSHOT</version>
<type>aar</type>
</dependency>
<dependency>
<groupId>com.mcxiaoke.volley</groupId>
<artifactId>library</artifactId>
<version>1.0.5</version>
<type>aar</type>
</dependency>
```
How do I use Glide?
-------------------
Checkout the GitHub wiki for pages on a variety of topics and links to javadocs.
......
......@@ -11,7 +11,9 @@ task wrapper(type: Wrapper) {
gradleVersion = '1.10'
}
evaluationDependsOnChildren();
evaluationDependsOn(":integration:volley")
evaluationDependsOn(":third_party:gif_decoder")
evaluationDependsOn(":library")
def getAndroidSdkDirectory() {
project("library").android.sdkDirectory
......@@ -44,7 +46,7 @@ getAndroidLibraryVariants().each { variant ->
task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) {
// Get the variant from each subproject that matches our current variant's name.
def childEquivalentChildVariants = getAndroidChildren().collect { project ->
def childEquivalentChildVariants = getAndroidChildren().collect { project ->
project.android.libraryVariants.findAll { type -> type.name == variant.name }
}.sum()
......
<?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>
<?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>
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"
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
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="AllowBackup" severity="ignore" />
</lint>
<?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>
target=android-19
# https://code.google.com/p/android/issues/detail?id=40487
renderscript.opt.level=O0
android.library=true
......@@ -12,10 +12,15 @@ 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) {
......
......@@ -73,7 +73,7 @@ android {
}
def getJarName() {
return "glide-${getVersionName()}.jar"
"glide-${getVersionName()}.jar"
}
// Build a jar, from http://stackoverflow.com/a/19037807/1002054.
......
POM_NAME=Glide Library
POM_ARTIFACT_ID=glide
POM_ARTIFACT_ID=library
POM_PACKAGING=aar
......@@ -9,7 +9,7 @@
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>glide</artifactId>
<artifactId>library</artifactId>
<packaging>aar</packaging>
<name>Glide Library</name>
......@@ -56,9 +56,10 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.bumptech.glide</groupId>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide-gif-decoder</artifactId>
<version>3.3.0-SNAPSHOT</version>
<type>aar</type>
</dependency>
</dependencies>
</project>
......@@ -14,7 +14,6 @@ import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.android.volley.RequestQueue;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.engine.cache.DiskCache;
......@@ -29,6 +28,7 @@ import com.bumptech.glide.load.model.file_descriptor.FileDescriptorModelLoader;
import com.bumptech.glide.load.model.file_descriptor.FileDescriptorResourceLoader;
import com.bumptech.glide.load.model.file_descriptor.FileDescriptorStringLoader;
import com.bumptech.glide.load.model.file_descriptor.FileDescriptorUriLoader;
import com.bumptech.glide.load.model.stream.HttpUrlGlideUrlLoader;
import com.bumptech.glide.load.model.stream.StreamFileLoader;
import com.bumptech.glide.load.model.stream.StreamModelLoader;
import com.bumptech.glide.load.model.stream.StreamResourceLoader;
......@@ -58,7 +58,6 @@ import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.target.ImageViewTargetFactory;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.target.ViewTarget;
import com.bumptech.glide.volley.VolleyUrlLoader;
import java.io.File;
import java.io.InputStream;
......@@ -81,7 +80,6 @@ public class Glide {
private static Glide GLIDE;
private final GenericLoaderFactory loaderFactory = new GenericLoaderFactory();
private final RequestQueue requestQueue;
private final Engine engine;
private final BitmapPool bitmapPool;
private final MemoryCache memoryCache;
......@@ -170,10 +168,8 @@ public class Glide {
GLIDE = null;
}
Glide(Engine engine, RequestQueue requestQueue, MemoryCache memoryCache, BitmapPool bitmapPool,
Context context) {
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context) {
this.engine = engine;
this.requestQueue = requestQueue;
this.bitmapPool = bitmapPool;
this.memoryCache = memoryCache;
......@@ -201,7 +197,7 @@ public class Glide {
register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
register(GlideUrl.class, InputStream.class, new VolleyUrlLoader.Factory(requestQueue));
register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
transcoderFactory.register(Bitmap.class, BitmapDrawable.class,
new BitmapDrawableTranscoder(context.getResources(), bitmapPool));
......@@ -257,13 +253,6 @@ public class Glide {
return loaderFactory;
}
/**
* Returns the {@link RequestQueue} Glide is using to fetch images over http/https.
*/
public RequestQueue getRequestQueue() {
return requestQueue;
}
/**
* Clears as much memory as possible.
*
......
......@@ -2,7 +2,6 @@ package com.bumptech.glide;
import android.content.Context;
import android.os.Build;
import com.android.volley.RequestQueue;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPoolAdapter;
......@@ -14,13 +13,11 @@ import com.bumptech.glide.load.engine.cache.LruResourceCache;
import com.bumptech.glide.load.engine.cache.MemoryCache;
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator;
import com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor;
import com.bumptech.glide.volley.RequestQueueWrapper;
import java.io.File;
import java.util.concurrent.ExecutorService;
public class GlideBuilder {
private RequestQueue requestQueue;
private Context context;
private Engine engine;
private BitmapPool bitmapPool;
......@@ -33,11 +30,6 @@ public class GlideBuilder {
this.context = context.getApplicationContext();
}
public GlideBuilder setRequestQueue(RequestQueue requestQueue) {
this.requestQueue = requestQueue;
return this;
}
public GlideBuilder setBitmapPool(BitmapPool bitmapPool) {
this.bitmapPool = bitmapPool;
return this;
......@@ -77,10 +69,6 @@ public class GlideBuilder {
diskCacheService = new FifoPriorityThreadPoolExecutor(1);
}
if (requestQueue == null) {
requestQueue = RequestQueueWrapper.getRequestQueue(context);
}
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
if (bitmapPool == null) {
if (Build.VERSION.SDK_INT >= 11) {
......@@ -108,6 +96,6 @@ public class GlideBuilder {
engine = new Engine(memoryCache, diskCache, resizeService, diskCacheService);
}
return new Glide(engine, requestQueue, memoryCache, bitmapPool, context);
return new Glide(engine, memoryCache, bitmapPool, context);
}
}
\ No newline at end of file
......@@ -8,9 +8,11 @@ import android.os.ParcelFileDescriptor;
import android.support.v4.app.FragmentActivity;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.load.data.HttpUrlFetcher;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.file_descriptor.FileDescriptorModelLoader;
import com.bumptech.glide.load.model.stream.HttpUrlGlideUrlLoader;
import com.bumptech.glide.load.model.stream.MediaStoreStreamLoader;
import com.bumptech.glide.load.model.stream.StreamByteArrayLoader;
import com.bumptech.glide.load.model.stream.StreamFileLoader;
......@@ -21,7 +23,6 @@ import com.bumptech.glide.load.model.stream.StreamUriLoader;
import com.bumptech.glide.manager.ConnectivityMonitor;
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
import com.bumptech.glide.manager.RequestTracker;
import com.bumptech.glide.volley.VolleyUrlLoader;
import java.io.File;
import java.io.InputStream;
......@@ -268,8 +269,7 @@ public class RequestManager {
/**
* Use the {@link ModelLoaderFactory} currently registered for {@link URL} to load the image represented by the
* given {@link URL}. Defaults to {@link com.bumptech.glide.volley.VolleyUrlLoader.Factory} and
* {@link VolleyUrlLoader} to load the given model.
* given {@link URL}. Defaults to {@link HttpUrlGlideUrlLoader} and {@link HttpUrlFetcher} to load the given model.
*
* @see #using(StreamModelLoader)
*
......
package com.bumptech.glide.load.data;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.model.GlideUrl;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpUrlFetcher implements DataFetcher<InputStream> {
private static final HttpUrlConnectionFactory DEFAULT_FACTORY = new DefaultHttpUrlConnectionFactory();
private GlideUrl glideUrl;
private final HttpUrlConnectionFactory factory;
private HttpURLConnection urlConnection;
private boolean isConnected;
private volatile boolean isCancelled;
public HttpUrlFetcher(GlideUrl glideUrl) {
this(glideUrl, DEFAULT_FACTORY);
}
HttpUrlFetcher(GlideUrl glideUrl, HttpUrlConnectionFactory factory) {
this.glideUrl = glideUrl;
this.factory = factory;
}
@Override
public InputStream loadData(Priority priority) throws Exception {
urlConnection = factory.build(glideUrl.toURL());
urlConnection.setConnectTimeout(2500);
urlConnection.setReadTimeout(2500);
urlConnection.setUseCaches(false);
urlConnection.setDoInput(true);
// Connect explicitly to avoid errors in decoders if connection fails.
urlConnection.connect();
synchronized (this) {
isConnected = true;
}
if (isCancelled) {
return null;
}
final int statusCode = urlConnection.getResponseCode();
if (statusCode / 100 == 2) {
return urlConnection.getInputStream();
} else {
if (statusCode == -1) {
throw new IOException("Unable to retrieve response code from HttpUrlConnection.");
}
throw new IOException("Request failed " + statusCode + ": " + urlConnection.getResponseMessage());
}
}
@Override
public void cleanup() {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
@Override
public String getId() {
return glideUrl.toString();
}
@Override
public void cancel() {
synchronized (this) {
if (!isConnected && urlConnection != null) {
urlConnection.disconnect();
}
}
isCancelled = true;
}
interface HttpUrlConnectionFactory {
public HttpURLConnection build(URL url) throws IOException;
}
private static class DefaultHttpUrlConnectionFactory implements HttpUrlConnectionFactory {
@Override
public HttpURLConnection build(URL url) throws IOException {
return (HttpURLConnection) url.openConnection();
}
}
}
package com.bumptech.glide.load.model.stream;
import android.content.Context;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.HttpUrlFetcher;
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 java.io.InputStream;
public class HttpUrlGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {
public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {
@Override
public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) {
return new HttpUrlGlideUrlLoader();
}
@Override
public void teardown() {
}
}
@Override
public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {
return new HttpUrlFetcher(model);
}
}
......@@ -13,10 +13,6 @@ import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.android.volley.Network;
import com.android.volley.NetworkResponse;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.NoCache;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
......@@ -39,8 +35,6 @@ import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.tests.GlideShadowLooper;
import com.bumptech.glide.volley.VolleyRequestFuture;
import com.bumptech.glide.volley.VolleyUrlLoader;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
......@@ -62,12 +56,10 @@ import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyObject;
......@@ -118,45 +110,21 @@ public class GlideTest {
}
});
// Make sure Volley does not actually perform any network requests.
Network network = mock(Network.class);
when(network.performRequest(any(com.android.volley.Request.class)))
.thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return new NetworkResponse(new byte[0]);
}
});
RequestQueue requestQueue = new RequestQueue(new NoCache(), network);
requestQueue.start();
Glide.setup(new GlideBuilder(Robolectric.application)
.setMemoryCache(mock(MemoryCache.class))
.setDiskCache(mock(DiskCache.class))
.setResizeService(service)
.setDiskCacheService(service)
.setRequestQueue(requestQueue));
// Sleep to avoid blocking the main thread while waiting for Volley's background thread to complete
// and for the result to be posted back to the main thread.
VolleyUrlLoader.FutureFactory futureFactory = mock(VolleyUrlLoader.FutureFactory.class);
VolleyRequestFuture<InputStream> future = new VolleyRequestFuture<InputStream>() {
@Override
public InputStream get() throws InterruptedException, ExecutionException {
for (int i = 0; i < 10 && !isDone(); i++) {
Thread.sleep(10);
// Make sure the result callback posted on the main thread actually runs.
Robolectric.runUiThreadTasks();
}
if (!isDone()) {
fail("Failed to get response from Volley in time");
}
return super.get();
}
};
when(futureFactory.build()).thenReturn(future);
Glide.get(getContext()).register(GlideUrl.class, InputStream.class,
new VolleyUrlLoader.Factory(Glide.get(getContext()).getRequestQueue(), futureFactory));
.setDiskCacheService(service));
DataFetcher<InputStream> mockStreamFetcher = mock(DataFetcher.class);
when(mockStreamFetcher.getId()).thenReturn("fakeId");
when(mockStreamFetcher.loadData(any(Priority.class))).thenReturn(new ByteArrayInputStream(new byte[0]));
ModelLoader<GlideUrl, InputStream> mockUrlLoader = mock(ModelLoader.class);
when(mockUrlLoader.getResourceFetcher(any(GlideUrl.class), anyInt(), anyInt())).thenReturn(mockStreamFetcher);
ModelLoaderFactory<GlideUrl, InputStream> mockUrlLoaderFactory = mock(ModelLoaderFactory.class);
when(mockUrlLoaderFactory.build(any(Context.class), any(GenericLoaderFactory.class)))
.thenReturn(mockUrlLoader);
Glide.get(getContext()).register(GlideUrl.class, InputStream.class, mockUrlLoaderFactory);
}
@After
......
package com.bumptech.glide.load.data;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.model.GlideUrl;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.CountDownLatch;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class HttpUrlFetcherTest {
private HttpURLConnection urlConnection;
private HttpUrlFetcher fetcher;
private GlideUrl glideUrl;
@Before
public void setUp() throws IOException {
urlConnection = mock(HttpURLConnection.class);
URL url = new URL("http://www.google.com");
HttpUrlFetcher.HttpUrlConnectionFactory factory = mock(HttpUrlFetcher.HttpUrlConnectionFactory.class);
when(factory.build(eq(url))).thenReturn(urlConnection);
glideUrl = mock(GlideUrl.class);
when(glideUrl.toURL()).thenReturn(url);
fetcher = new HttpUrlFetcher(glideUrl, factory);
when(urlConnection.getResponseCode()).thenReturn(200);
}
@Test
public void testReturnsModelAsString() {
final String expected = "fakeId";
when(glideUrl.toString()).thenReturn(expected);
assertEquals(expected, fetcher.getId());
}
@Test
public void testSetsReadTimeout() throws Exception {
fetcher.loadData(Priority.HIGH);
verify(urlConnection).setReadTimeout(eq(2500));
}
@Test
public void testSetsConnectTimeout() throws Exception {
fetcher.loadData(Priority.IMMEDIATE);
verify(urlConnection).setConnectTimeout(eq(2500));
}
@Test
public void testReturnsInputStreamOnStatusOk() throws Exception {
InputStream expected = new ByteArrayInputStream(new byte[0]);
when(urlConnection.getResponseCode()).thenReturn(200);
when(urlConnection.getInputStream()).thenReturn(expected);
assertEquals(expected, fetcher.loadData(Priority.NORMAL));
}
@Test(expected = IOException.class)
public void testThrowsIfStatusCodeIsNegativeOne() throws Exception {
when(urlConnection.getResponseCode()).thenReturn(-1);
fetcher.loadData(Priority.HIGH);
}
@Test(expected = IOException.class)
public void testThrowsIfStatusCodeIs300() throws Exception {
when(urlConnection.getResponseCode()).thenReturn(300);
fetcher.loadData(Priority.HIGH);
}
@Test(expected = IOException.class)
public void testThrowsIfStatusCodeIs500() throws Exception {
when(urlConnection.getResponseCode()).thenReturn(500);
fetcher.loadData(Priority.HIGH);
}
@Test
public void testReturnsNullIfCancelledBeforeConnects() throws Exception {
InputStream notExpected = new ByteArrayInputStream(new byte[0]);
when(urlConnection.getInputStream()).thenReturn(notExpected);
fetcher.cancel();
assertNull(fetcher.loadData(Priority.LOW));
}
@Test
public void testDisconnectsUrlOnCleanup() throws Exception {
fetcher.loadData(Priority.HIGH);
fetcher.cleanup();
verify(urlConnection).disconnect();
}
@Test
public void testDoesNotThrowIfCleanupCalledBeforeStarted() {
fetcher.cleanup();
}
@Test
public void testDoesNotThrowIfCancelCalledBeforeStart() {
fetcher.cancel();
}
@Test
public void testCancelDoesNotDisconnectIfAlreadyConnected() throws Exception {
fetcher.loadData(Priority.HIGH);
fetcher.cancel();
verify(urlConnection, never()).disconnect();
}
@Test
public void testDisconnectsUrlConnectionOnCancelIfNotYetCancelled() throws IOException, InterruptedException {
final CountDownLatch mainThreadLatch = new CountDownLatch(1);
final CountDownLatch countDownLatch = new CountDownLatch(1);
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
mainThreadLatch.countDown();
countDownLatch.await();
return null;
}
}).when(urlConnection).connect();
Thread bg = new Thread() {
@Override
public void run() {
try {
fetcher.loadData(Priority.HIGH);
} catch (Exception e) {
e.printStackTrace();
}
}
};
bg.start();
mainThreadLatch.await();
fetcher.cancel();
countDownLatch.countDown();
bg.join();
verify(urlConnection).connect();
verify(urlConnection).disconnect();
}
}
\ No newline at end of file
package com.bumptech.glide.load.model.stream;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.HttpUrlFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
public class HttpUrlGlideUrlLoaderTest {
private HttpUrlGlideUrlLoader loader;
private GlideUrl model;
@SuppressWarnings("unchecked")
@Before
public void setUp() {
loader = new HttpUrlGlideUrlLoader();
model = mock(GlideUrl.class);
}
@Test
public void testReturnsValidFetcher() {
DataFetcher<InputStream> result = loader.getResourceFetcher(model, 100, 100);
assertTrue(result instanceof HttpUrlFetcher);
}
}
\ No newline at end of file
......@@ -18,6 +18,7 @@
<modules>
<module>library</module>
<module>third_party</module>
<module>integration</module>
<module>samples</module>
</modules>
......@@ -33,11 +34,6 @@
<version>4.4.2_r3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mcxiaoke.volley</groupId>
<artifactId>library</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<build>
......
......@@ -16,10 +16,9 @@
<dependencies>
<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide</artifactId>
<artifactId>library</artifactId>
<version>3.3.0-SNAPSHOT</version>
<type>aar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.actionbarsherlock</groupId>
......@@ -33,5 +32,10 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mcxiaoke.volley</groupId>
<artifactId>library</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
</project>
package com.bumptech.glide.samples.flickr;
import android.annotation.TargetApi;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.Fragment;
......@@ -70,6 +71,7 @@ public class FlickrSearchActivity extends SherlockFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Glide.get(this).register(Photo.class, InputStream.class, new FlickrModelLoader.Factory());
setContentView(R.layout.flickr_search_activity);
......@@ -127,7 +129,7 @@ public class FlickrSearchActivity extends SherlockFragmentActivity {
pager.setAdapter(new FlickrPagerAdapter(getSupportFragmentManager()));
Api.get(Glide.get(this).getRequestQueue()).registerSearchListener(searchListener);
Api.get(this).registerSearchListener(searchListener);
if (savedInstanceState != null) {
String savedSearchString = savedInstanceState.getString(STATE_SEARCH_STRING);
if (!TextUtils.isEmpty(savedSearchString)) {
......@@ -147,9 +149,10 @@ public class FlickrSearchActivity extends SherlockFragmentActivity {
@Override
protected void onDestroy() {
super.onDestroy();
Api.get(Glide.get(this).getRequestQueue()).unregisterSearchListener(searchListener);
Api.get(this).unregisterSearchListener(searchListener);
}
@TargetApi(14)
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
......@@ -179,7 +182,7 @@ public class FlickrSearchActivity extends SherlockFragmentActivity {
searchLoading.setVisibility(View.VISIBLE);
searchTerm.setText(getString(R.string.searching_for, currentSearchString));
Api.get(Glide.get(this).getRequestQueue()).search(currentSearchString);
Api.get(this).search(currentSearchString);
}
private static class TabListener implements ActionBar.TabListener {
......
package com.bumptech.glide.samples.flickr.api;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.android.volley.DefaultRetryPolicy;
......@@ -8,6 +9,7 @@ import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -85,9 +87,9 @@ public class Api {
public void onSearchFailed(String searchString, Exception e);
}
public static Api get(RequestQueue requestQueue) {
public static Api get(Context context) {
if (API == null) {
API = new Api(requestQueue);
API = new Api(context);
}
return API;
}
......@@ -96,8 +98,8 @@ public class Api {
private final Set<SearchListener> searchListeners = new HashSet<SearchListener>();
private SearchResult lastSearchResult;
protected Api(RequestQueue requestQueue) {
this.requestQueue = requestQueue;
protected Api(Context context) {
this.requestQueue = Volley.newRequestQueue(context.getApplicationContext());
}
public void registerSearchListener(SearchListener searchListener) {
......
include ':library'
include ':third_party:gif_decoder'
include ':samples:flickr'
\ No newline at end of file
include ':samples:flickr'
include ':integration:volley'
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册