Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GlideModule for lazily initialization. #311

Merged
merged 2 commits into from
Jan 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions integration/okhttp/src/main/AndroidManifest.xml
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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.bumptech.glide.integration.okhttp;

import android.content.Context;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
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 applyOptions(Context context, GlideBuilder builder) {
// Do nothing.
}

@Override
public void registerComponents(Context context, Glide glide) {
glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
}
}
6 changes: 5 additions & 1 deletion integration/volley/src/main/AndroidManifest.xml
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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.bumptech.glide.integration.volley;

import android.content.Context;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
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 applyOptions(Context context, GlideBuilder builder) {
// Do nothing.
}

@Override
public void registerComponents(Context context, Glide glide) {
glide.register(GlideUrl.class, InputStream.class, new VolleyUrlLoader.Factory(context));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
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 com.bumptech.glide.GlideBuilder;

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 applyOptions(Context context, GlideBuilder builder) { }

@Override
public void registerComponents(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 applyOptions(Context context, GlideBuilder builder) { }

@Override
public void registerComponents(Context context, Glide glide) { }

@Override
public boolean equals(Object o) {
return o instanceof TestModule2;
}

@Override
public int hashCode() {
return super.hashCode();
}
}
}
23 changes: 22 additions & 1 deletion library/src/main/java/com/bumptech/glide/Glide.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import com.bumptech.glide.load.resource.transcode.TranscoderRegistry;
import com.bumptech.glide.manager.RequestManagerRetriever;
import com.bumptech.glide.module.GlideModule;
import com.bumptech.glide.module.ManifestParser;
import com.bumptech.glide.provider.DataLoadProvider;
import com.bumptech.glide.provider.DataLoadProviderRegistry;
import com.bumptech.glide.request.FutureTarget;
Expand All @@ -69,6 +71,7 @@
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

/**
* A singleton to present a simple static interface for building requests with {@link BitmapRequestBuilder} and
Expand Down Expand Up @@ -144,7 +147,17 @@ public static Glide get(Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
glide = new GlideBuilder(context).createGlide();
Context applicationContext = context.getApplicationContext();
List<GlideModule> modules = new ManifestParser(applicationContext).parse();

GlideBuilder builder = new GlideBuilder(applicationContext);
for (GlideModule module : modules) {
module.applyOptions(applicationContext, builder);
}
glide = builder.createGlide();
for (GlideModule module : modules) {
module.registerComponents(applicationContext, glide);
}
}
}
}
Expand All @@ -157,7 +170,10 @@ public static Glide get(Context context) {
* {@link #setup(GlideBuilder)}.
*
* @see #setup(GlideBuilder)
*
* @deprecated Use {@link com.bumptech.glide.module.GlideModule} instead. Scheduled to be removed in Glide 4.0.
*/
@Deprecated
public static boolean isSetup() {
return glide != null;
}
Expand All @@ -168,9 +184,11 @@ public static boolean isSetup() {
*
* @see #isSetup()
*
* @deprecated Use {@link com.bumptech.glide.module.GlideModule} instead. Scheduled to be removed in Glide 4.0.
* @param builder The builder.
* @throws IllegalArgumentException if the Glide singleton has already been created.
*/
@Deprecated
public static void setup(GlideBuilder builder) {
if (isSetup()) {
throw new IllegalArgumentException("Glide is already setup, check with isSetup() first");
Expand Down Expand Up @@ -461,11 +479,14 @@ public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLo
* Removes any {@link ModelLoaderFactory} registered for the given model and resource classes if one exists. If a
* {@link ModelLoaderFactory} is removed, its {@link ModelLoaderFactory#teardown()}} method will be called.
*
* @deprecated Use {@link #register(Class, Class, com.bumptech.glide.load.model.ModelLoaderFactory)} to replace
* a registered loader rather than simply removing it.
* @param modelClass The model class.
* @param resourceClass The resource class.
* @param <T> The type of the model.
* @param <Y> The type of the resource.
*/
@Deprecated
public <T, Y> void unregister(Class<T> modelClass, Class<Y> resourceClass) {
ModelLoaderFactory<T, Y> removed = loaderFactory.unregister(modelClass, resourceClass);
if (removed != null) {
Expand Down
Loading