forked from bumptech/glide
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add GlideModule for lazily initialization.
Fixes bumptech#299.
- Loading branch information
Showing
14 changed files
with
381 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.bumptech.glide.integration.okhttp"> | ||
<application /> | ||
|
||
<application> | ||
<meta-data | ||
android:name="com.bumptech.glide.integration.okhttp.OkHttpGlideModule" | ||
android:value="GlideModule" /> | ||
</application> | ||
</manifest> |
27 changes: 27 additions & 0 deletions
27
...gration/okhttp/src/main/java/com/bumptech/glide/integration/okhttp/OkHttpGlideModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.bumptech.glide.integration.okhttp; | ||
|
||
import android.content.Context; | ||
|
||
import com.bumptech.glide.Glide; | ||
import com.bumptech.glide.load.model.GlideUrl; | ||
import com.bumptech.glide.module.GlideModule; | ||
|
||
import java.io.InputStream; | ||
|
||
/** | ||
* A {@link com.bumptech.glide.module.GlideModule} implementation to replace Glide's default | ||
* {@link java.net.HttpURLConnection} based {@link com.bumptech.glide.load.model.ModelLoader} with an OkHttp based | ||
* {@link com.bumptech.glide.load.model.ModelLoader}. | ||
* | ||
* <p> | ||
* If you're using gradle, you can include this module simply by depending on the aar, the module will be merged | ||
* in by manifest merger. For other build systems or for more more information, see | ||
* {@link com.bumptech.glide.module.GlideModule}. | ||
* </p> | ||
*/ | ||
public class OkHttpGlideModule implements GlideModule { | ||
@Override | ||
public void initialize(Context context, Glide glide) { | ||
glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.bumptech.glide.integration.volley"> | ||
<application /> | ||
<application> | ||
<meta-data | ||
android:name="com.bumptech.glide.integration.volley.VolleyGlideModule" | ||
android:value="GlideModule" /> | ||
</application> | ||
</manifest> |
27 changes: 27 additions & 0 deletions
27
...gration/volley/src/main/java/com/bumptech/glide/integration/volley/VolleyGlideModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.bumptech.glide.integration.volley; | ||
|
||
import android.content.Context; | ||
|
||
import com.bumptech.glide.Glide; | ||
import com.bumptech.glide.load.model.GlideUrl; | ||
import com.bumptech.glide.module.GlideModule; | ||
|
||
import java.io.InputStream; | ||
|
||
/** | ||
* A {@link com.bumptech.glide.module.GlideModule} implementation to replace Glide's default | ||
* {@link java.net.HttpURLConnection} based {@link com.bumptech.glide.load.model.ModelLoader} with a Volley based | ||
* {@link com.bumptech.glide.load.model.ModelLoader}. | ||
* | ||
* <p> | ||
* If you're using gradle, you can include this module simply by depending on the aar, the module will be merged | ||
* in by manifest merger. For other build systems or for more more information, see | ||
* {@link com.bumptech.glide.module.GlideModule}. | ||
* </p> | ||
*/ | ||
public class VolleyGlideModule implements GlideModule { | ||
@Override | ||
public void initialize(Context context, Glide glide) { | ||
glide.register(GlideUrl.class, InputStream.class, new VolleyUrlLoader.Factory(context)); | ||
} | ||
} |
145 changes: 145 additions & 0 deletions
145
library/src/androidTest/java/com/bumptech/glide/module/ManifestParserTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package com.bumptech.glide.module; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
import static org.mockito.Matchers.eq; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
import android.content.Context; | ||
import android.content.pm.ApplicationInfo; | ||
import android.content.pm.PackageManager; | ||
import android.os.Bundle; | ||
|
||
import com.bumptech.glide.Glide; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.Mock; | ||
import org.mockito.MockitoAnnotations; | ||
import org.robolectric.RobolectricTestRunner; | ||
import org.robolectric.annotation.Config; | ||
|
||
import java.util.List; | ||
|
||
@RunWith(RobolectricTestRunner.class) | ||
@Config(manifest = Config.NONE, emulateSdk = 18) | ||
public class ManifestParserTest { | ||
private static final String MODULE_VALUE = "GlideModule"; | ||
|
||
@Mock Context context; | ||
private ManifestParser parser; | ||
private ApplicationInfo applicationInfo; | ||
|
||
@Before | ||
public void setUp() throws PackageManager.NameNotFoundException { | ||
MockitoAnnotations.initMocks(this); | ||
applicationInfo = new ApplicationInfo(); | ||
applicationInfo.metaData = new Bundle(); | ||
|
||
String packageName = "com.bumptech.test"; | ||
when(context.getPackageName()).thenReturn(packageName); | ||
|
||
PackageManager pm = mock(PackageManager.class); | ||
when(pm.getApplicationInfo(eq(packageName), eq(PackageManager.GET_META_DATA))) | ||
.thenReturn(applicationInfo); | ||
when(context.getPackageManager()).thenReturn(pm); | ||
|
||
parser = new ManifestParser(context); | ||
} | ||
|
||
@Test | ||
public void testParse_returnsEmptyListIfNoModulesListed() { | ||
assertThat(parser.parse()).isEmpty(); | ||
} | ||
|
||
@Test | ||
public void testParse_withSingleValidModuleName_returnsListContainingModule() { | ||
addModuleToManifest(TestModule1.class); | ||
|
||
List<GlideModule> modules = parser.parse(); | ||
assertThat(modules).hasSize(1); | ||
assertThat(modules.get(0)).isInstanceOf(TestModule1.class); | ||
} | ||
|
||
@Test | ||
public void testParse_withMultipleValidModuleNames_returnsListContainingModules() { | ||
addModuleToManifest(TestModule1.class); | ||
addModuleToManifest(TestModule2.class); | ||
|
||
List<GlideModule> modules = parser.parse(); | ||
assertThat(modules).hasSize(2); | ||
|
||
assertThat(modules).contains(new TestModule1()); | ||
assertThat(modules).contains(new TestModule2()); | ||
} | ||
|
||
@Test | ||
public void testParse_withValidModuleName_ignoresMetadataWithoutGlideModuleValue() { | ||
applicationInfo.metaData.putString(TestModule1.class.getName(), MODULE_VALUE + "test"); | ||
|
||
assertThat(parser.parse()).isEmpty(); | ||
} | ||
|
||
@Test(expected = RuntimeException.class) | ||
public void testThrows_whenModuleNameNotFound() { | ||
addToManifest("fakeClassName"); | ||
|
||
parser.parse(); | ||
} | ||
|
||
@Test(expected = RuntimeException.class) | ||
public void testThrows_whenClassInManifestIsNotAModule() { | ||
addModuleToManifest(InvalidClass.class); | ||
|
||
parser.parse(); | ||
} | ||
|
||
@Test(expected = RuntimeException.class) | ||
public void testThrows_whenPackageNameNotFound() { | ||
when(context.getPackageName()).thenReturn("fakePackageName"); | ||
|
||
parser.parse(); | ||
} | ||
|
||
private void addModuleToManifest(Class<?> moduleClass) { | ||
addToManifest(moduleClass.getName()); | ||
} | ||
|
||
private void addToManifest(String key) { | ||
applicationInfo.metaData.putString(key, MODULE_VALUE); | ||
} | ||
|
||
public static class InvalidClass { } | ||
|
||
public static class TestModule1 implements GlideModule { | ||
@Override | ||
public void initialize(Context context, Glide glide) { } | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
return o instanceof TestModule1; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return super.hashCode(); | ||
} | ||
} | ||
|
||
public static class TestModule2 implements GlideModule { | ||
|
||
@Override | ||
public void initialize(Context context, Glide glide) { } | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
return o instanceof TestModule2; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return super.hashCode(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
library/src/main/java/com/bumptech/glide/module/GlideModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.bumptech.glide.module; | ||
|
||
import android.content.Context; | ||
|
||
import com.bumptech.glide.Glide; | ||
|
||
/** | ||
* An interface allowing lazy registration of {@link com.bumptech.glide.load.model.ModelLoader ModelLoaders}. | ||
* | ||
* <p> | ||
* To use this interface: | ||
* <ol> | ||
* <li> | ||
* Implement the GlideModule interface in a class with public visibility, calling | ||
* {@link com.bumptech.glide.Glide#register(Class, Class, com.bumptech.glide.load.model.ModelLoaderFactory)} | ||
* for each {@link com.bumptech.glide.load.model.ModelLoader} you'd like to register: | ||
* <pre> | ||
* <code> | ||
* public class FlickrGlideModule implements GlideModule { | ||
* {@literal @}Override | ||
* public void initialize(Context context, Glide glide) { | ||
* glide.register(Model.class, Data.class, new MyModelLoader()); | ||
* } | ||
* } | ||
* </code> | ||
* </pre> | ||
* </li> | ||
* <li> | ||
* Add your implementation to your list of keeps in your proguard.cfg file: | ||
* <pre> | ||
* {@code | ||
* -keepnames class * com.bumptech.glide.samples.flickr.FlickrGlideModule | ||
* } | ||
* </pre> | ||
* </li> | ||
* <li> | ||
* Add a metadata tag to your AndroidManifest.xml with your GlideModule implementation's fully qualified | ||
* classname as the key, and {@code GlideModule} as the value: | ||
* <pre> | ||
* {@code | ||
* <meta-data | ||
* android:name="com.bumptech.glide.samples.flickr.FlickrGlideModule" | ||
* android:value="GlideModule" /> | ||
* } | ||
* </pre> | ||
* </li> | ||
* </ol> | ||
* </p> | ||
* | ||
* <p> | ||
* All implementations must be publicly visible and contain only an empty constructor so they can be instantiated | ||
* via reflection when Glide is lazily initialized. | ||
* </p> | ||
*/ | ||
public interface GlideModule { | ||
void initialize(Context context, Glide glide); | ||
} |
63 changes: 63 additions & 0 deletions
63
library/src/main/java/com/bumptech/glide/module/ManifestParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.bumptech.glide.module; | ||
|
||
import android.content.Context; | ||
import android.content.pm.ApplicationInfo; | ||
import android.content.pm.PackageManager; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* Parses {@link com.bumptech.glide.module.GlideModule} references out of the AndroidManifest file. | ||
*/ | ||
public final class ManifestParser { | ||
private static final String GLIDE_MODULE_VALUE = "GlideModule"; | ||
|
||
private final Context context; | ||
|
||
public ManifestParser(Context context) { | ||
this.context = context; | ||
} | ||
|
||
public List<GlideModule> parse() { | ||
List<GlideModule> modules = new ArrayList<GlideModule>(); | ||
try { | ||
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( | ||
context.getPackageName(), PackageManager.GET_META_DATA); | ||
if (appInfo.metaData != null) { | ||
for (String key : appInfo.metaData.keySet()) { | ||
if (GLIDE_MODULE_VALUE.equals(appInfo.metaData.getString(key))) { | ||
modules.add(parseModule(key)); | ||
} | ||
} | ||
} | ||
} catch (PackageManager.NameNotFoundException e) { | ||
throw new RuntimeException("Unable to find metadata to parse GlideModules", e); | ||
} | ||
|
||
return modules; | ||
} | ||
|
||
private static GlideModule parseModule(String className) { | ||
Class<?> clazz; | ||
try { | ||
clazz = Class.forName(className); | ||
} catch (ClassNotFoundException e) { | ||
throw new IllegalArgumentException("Unable to find GlideModule implementation", e); | ||
} | ||
|
||
Object module; | ||
try { | ||
module = clazz.newInstance(); | ||
} catch (InstantiationException e) { | ||
throw new RuntimeException("Unable to instantiate GlideModule implementation for " + clazz, e); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException("Unable to instantiate GlideModule implementation for " + clazz, e); | ||
} | ||
|
||
if (!(module instanceof GlideModule)) { | ||
throw new RuntimeException("Expected instanceof GlideModule, but found: " + module); | ||
} | ||
return (GlideModule) module; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
samples/flickr/src/main/java/com/bumptech/glide/samples/flickr/FlickrGlideModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.bumptech.glide.samples.flickr; | ||
|
||
import android.content.Context; | ||
|
||
import com.bumptech.glide.Glide; | ||
import com.bumptech.glide.module.GlideModule; | ||
import com.bumptech.glide.samples.flickr.api.Photo; | ||
|
||
import java.io.InputStream; | ||
|
||
/** | ||
* {@link com.bumptech.glide.module.GlideModule} for the Flickr sample app. | ||
*/ | ||
public class FlickrGlideModule implements GlideModule { | ||
@Override | ||
public void initialize(Context context, Glide glide) { | ||
glide.register(Photo.class, InputStream.class, new FlickrModelLoader.Factory()); | ||
} | ||
} |
Oops, something went wrong.