提交 b51cd256 编写于 作者: S Sam Judd

Handle asset manager Uris.

Fixes #155.
上级 b4ed2bbf
......@@ -33,17 +33,25 @@ public class UriLoaderTest {
private UriLoader loader;
private DataFetcher<InputStream> localUriFetcher;
private ModelLoader<GlideUrl, InputStream> urlLoader;
private DataFetcher<InputStream> assetUriFetcher;
@SuppressWarnings("uncecked")
@Before
public void setUp() throws Exception {
urlLoader = mock(ModelLoader.class);
localUriFetcher = mock(DataFetcher.class);
assetUriFetcher = mock(DataFetcher.class);
loader = new UriLoader<InputStream>(Robolectric.application, urlLoader) {
@Override
protected DataFetcher<InputStream> getLocalUriFetcher(Context context, Uri uri) {
return localUriFetcher;
}
@Override
protected DataFetcher<InputStream> getAssetPathFetcher(Context context, String path) {
return assetUriFetcher;
}
};
}
......@@ -68,6 +76,13 @@ public class UriLoaderTest {
assertEquals(localUriFetcher, dataFetcher);
}
@Test
public void testHandlesAssetUris() {
Uri assetUri = Uri.parse("file:///android_asset/assetName");
DataFetcher fetcher = loader.getResourceFetcher(assetUri, IMAGE_SIDE, IMAGE_SIDE);
assertEquals(assetUriFetcher, fetcher);
}
@Test
public void testHandlesHttpUris() throws MalformedURLException {
Uri httpUri = Uri.parse("http://www.google.com");
......
package com.bumptech.glide.load.data;
import android.content.res.AssetManager;
import android.util.Log;
import com.bumptech.glide.Priority;
import java.io.IOException;
/**
* An abstract class for obtaining data for an asset path using an {@link android.content.res.AssetManager}.
*
* @param <T> The type of data obtained from the asset path (InputStream, FileDescriptor etc).
*/
public abstract class AssetPathFetcher<T> implements DataFetcher<T> {
private static final String TAG = "AssetUriFetcher";
private final String assetPath;
private final AssetManager assetManager;
private T data;
public AssetPathFetcher(AssetManager assetManager, String assetPath) {
this.assetManager = assetManager;
this.assetPath = assetPath;
}
@Override
public T loadData(Priority priority) throws Exception {
data = loadResource(assetManager, assetPath);
return data;
}
@Override
public void cleanup() {
if (data == null) {
return;
}
try {
close(data);
} catch (IOException e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Failed to close data", e);
}
}
}
@Override
public String getId() {
return assetPath;
}
@Override
public void cancel() {
// Do nothing.
}
/**
* Opens the given asset path with the given {@link android.content.res.AssetManager} and returns the conrete data
* type returned by the AssetManager.
*
* @param assetManager An AssetManager to use to open the given path.
* @param path A string path pointing to a resource in assets to open.
*/
protected abstract T loadResource(AssetManager assetManager, String path) throws IOException;
/**
* Closes the concrete data type if necessary.
*
* @param data The data to close.
* @throws IOException
*/
protected abstract void close(T data) throws IOException;
}
package com.bumptech.glide.load.data;
import android.content.res.AssetManager;
import android.os.ParcelFileDescriptor;
import java.io.IOException;
/**
* Fetches an {@link android.os.ParcelFileDescriptor} for an asset path.
*/
public class FileDescriptorAssetPathFetcher extends AssetPathFetcher<ParcelFileDescriptor> {
public FileDescriptorAssetPathFetcher(AssetManager assetManager, String assetPath) {
super(assetManager, assetPath);
}
@Override
protected ParcelFileDescriptor loadResource(AssetManager assetManager, String path) throws IOException {
return assetManager.openFd(path).getParcelFileDescriptor();
}
@Override
protected void close(ParcelFileDescriptor data) throws IOException {
data.close();
}
}
package com.bumptech.glide.load.data;
import android.content.res.AssetManager;
import java.io.IOException;
import java.io.InputStream;
/**
* Fetches an {@link java.io.InputStream} for an asset path.
*/
public class StreamAssetPathFetcher extends AssetPathFetcher<InputStream> {
public StreamAssetPathFetcher(AssetManager assetManager, String assetPath) {
super(assetManager, assetPath);
}
@Override
protected InputStream loadResource(AssetManager assetManager, String path) throws IOException {
return assetManager.open(path);
}
@Override
protected void close(InputStream data) throws IOException {
data.close();
}
}
package com.bumptech.glide.load.model;
import android.content.ContentResolver;
import android.net.Uri;
/**
* A utility class for parsing Asset uris that look like: file:///android_asset/some/path/in/assets/folder.
*/
class AssetUriParser {
private static final String ASSET_PATH_SEGMENT = "android_asset";
private static final String ASSET_PREFIX = ContentResolver.SCHEME_FILE + ":///" + ASSET_PATH_SEGMENT + "/";
private static final int ASSET_PREFIX_LENGTH = ASSET_PREFIX.length();
/**
* Returns true if the given {@link android.net.Uri} matches the asset uri pattern.
*/
public static boolean isAssetUri(Uri uri) {
return ContentResolver.SCHEME_FILE.equals(uri.getScheme()) && !uri.getPathSegments().isEmpty()
&& ASSET_PATH_SEGMENT.equals(uri.getPathSegments().get(0));
}
/**
* Returns the string path for the given asset uri.
*
* <p>
* Assumes the given {@link android.net.Uri} is in fact an asset uri.
* </p>
*/
public static String toAssetPath(Uri uri) {
return uri.toString().substring(ASSET_PREFIX_LENGTH);
}
}
......@@ -13,6 +13,10 @@ import com.bumptech.glide.load.data.DataFetcher;
* @param <T> The type of data that will be retrieved for {@link android.net.Uri}s.
*/
public abstract class UriLoader<T> implements ModelLoader<Uri, T> {
private static final String ASSET_PATH_SEGMENT = "android_asset";
private static final String ASSET_PREFIX = ContentResolver.SCHEME_FILE + ":///" + ASSET_PATH_SEGMENT + "/";
private static final int ASSET_PREFIX_LENGTH = ASSET_PREFIX.length();
private final Context context;
private final ModelLoader<GlideUrl, T> urlLoader;
......@@ -27,7 +31,12 @@ public abstract class UriLoader<T> implements ModelLoader<Uri, T> {
DataFetcher<T> result = null;
if (isLocalUri(scheme)) {
result = getLocalUriFetcher(context, model);
if (AssetUriParser.isAssetUri(model)) {
String path = AssetUriParser.toAssetPath(model);
result = getAssetPathFetcher(context, path);
} else {
result = getLocalUriFetcher(context, model);
}
} else if (urlLoader != null && ("http".equals(scheme) || "https".equals(scheme))) {
result = urlLoader.getResourceFetcher(new GlideUrl(model.toString()), width, height);
}
......@@ -37,6 +46,8 @@ public abstract class UriLoader<T> implements ModelLoader<Uri, T> {
protected abstract DataFetcher<T> getLocalUriFetcher(Context context, Uri uri);
protected abstract DataFetcher<T> getAssetPathFetcher(Context context, String path);
private static boolean isLocalUri(String scheme) {
return ContentResolver.SCHEME_FILE.equals(scheme)
|| ContentResolver.SCHEME_CONTENT.equals(scheme)
......
......@@ -4,13 +4,14 @@ import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.FileDescriptorAssetPathFetcher;
import com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher;
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.model.UriLoader;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher;
/**
* A {@link ModelLoader} For translating {@link Uri} models for local uris into {@link ParcelFileDescriptor} data.
......@@ -45,4 +46,9 @@ public class FileDescriptorUriLoader extends UriLoader<ParcelFileDescriptor> imp
protected DataFetcher<ParcelFileDescriptor> getLocalUriFetcher(Context context, Uri uri) {
return new FileDescriptorLocalUriFetcher(context, uri);
}
@Override
protected DataFetcher<ParcelFileDescriptor> getAssetPathFetcher(Context context, String assetPath) {
return new FileDescriptorAssetPathFetcher(context.getApplicationContext().getAssets(), assetPath);
}
}
......@@ -3,13 +3,14 @@ package com.bumptech.glide.load.model.stream;
import android.content.Context;
import android.net.Uri;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.StreamAssetPathFetcher;
import com.bumptech.glide.load.data.StreamLocalUriFetcher;
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.model.UriLoader;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.StreamLocalUriFetcher;
import java.io.InputStream;
......@@ -48,4 +49,9 @@ public class StreamUriLoader extends UriLoader<InputStream> implements StreamMod
protected DataFetcher<InputStream> getLocalUriFetcher(Context context, Uri uri) {
return new StreamLocalUriFetcher(context, uri);
}
@Override
protected DataFetcher<InputStream> getAssetPathFetcher(Context context, String assetPath) {
return new StreamAssetPathFetcher(context.getApplicationContext().getAssets(), assetPath);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册