android - 如何通过 HTTP POST 方法使用 Glide 下载图像

标签 android android-glide image-loading

服务器提供了通过Post请求加载图片的API,其body如下所示

{
 "image_id": someId,
 "session_id": "someId"
}
响应 - 流。
如何使用 Glide 通过 HTTP POST 方法下载图像?

最佳答案

通过 HTTP POST 方法使用 Glide & Retrofit 2 加载图像的算法:

1)创建接口(interface),所有通过HTTP POST方式加载图片的请求都要实现该接口(interface):

public interface CacheableRequest {
    String getCacheKey();
}

2) 创建要加载的模型,它将用作 Glide.with(context).load(model) 的参数:

import java.io.IOException;
import java.io.InputStream;

import okhttp3.ResponseBody;
import retrofit2.Call;

public class RetrofitStream {

    private final Call<ResponseBody> call;
    private final CacheableRequest request;

    public RetrofitStream(Call<ResponseBody> call, CacheableRequest request) {
        this.call = call;
        this.request = request;
    }

    public InputStream getStream() throws IOException {
        return call.execute().body().byteStream();
    }

    public String getCacheKey() {
        return request.getCacheKey();
    }
}

3) 创建 com.bumptech.glide.load.data.DataFetcher 的实现:

import android.support.annotation.Nullable;

import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;

import java.io.IOException;
import java.io.InputStream;

public class RetrofitFetcher implements DataFetcher<InputStream> {

    private final RetrofitStream retrofitStream;
    private InputStream stream;

    public RetrofitFetcher(RetrofitStream retrofitStream) {
        this.retrofitStream = retrofitStream;
    }

    @Nullable
    @Override
    public InputStream loadData(Priority priority) throws Exception {
        return stream = retrofitStream.getStream();
    }

    @Override
    public void cleanup() {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException ignored) {
            }
        }
    }

    @Override
    public String getId() {
        return retrofitStream.getCacheKey();
    }

    @Override
    public void cancel() {

    }
}

4) 创建 com.bumptech.glide.load.model.ModelLoader 的实现:

import android.content.Context;
import android.support.annotation.Keep;
import android.support.annotation.Nullable;

import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelCache;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;

import java.io.InputStream;

public class RetrofitStreamLoader implements ModelLoader<RetrofitStream, InputStream> {

    private final ModelCache<RetrofitStream, RetrofitStream> modelCache;

    @Keep
    public RetrofitStreamLoader() {
        this(null);
    }

    public RetrofitStreamLoader(@Nullable ModelCache<RetrofitStream, RetrofitStream> modelCache) {
        this.modelCache = modelCache;
    }

    @Override
    public DataFetcher<InputStream> getResourceFetcher(RetrofitStream model, int width, int height) {
        // GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time spent parsing urls.
        RetrofitStream stream = model;
        if (modelCache != null) {
            stream = modelCache.get(model, 0, 0);
            if (stream == null) {
                modelCache.put(model, 0, 0, model);
                stream = model;
            }
        }
        return new RetrofitFetcher(stream);
    }

    /**
     * The default factory for {@link RetrofitStreamLoader}s.
     */
    public static class Factory implements ModelLoaderFactory<RetrofitStream, InputStream> {

        private final ModelCache<RetrofitStream, RetrofitStream> modelCache = new ModelCache<>(500);

        @Override
        public ModelLoader<RetrofitStream, InputStream> build(Context context, GenericLoaderFactory factories) {
            return new RetrofitStreamLoader(modelCache);
        }

        @Override
        public void teardown() {
            // Do nothing.
        }
    }
}

5) 创建GlideModule的实现,允许配置Glide

import android.content.Context;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.module.GlideModule;

import java.io.InputStream;

public class RetrofitGlideModule implements GlideModule {

    private final static int IMAGES_CACHE_MAX_BYTE_SIZE = 20 * 1024 * 1024;
    private final static String IMAGES_CACHE_PATH = "images";

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, IMAGES_CACHE_PATH, IMAGES_CACHE_MAX_BYTE_SIZE))
                .setDecodeFormat(DecodeFormat.PREFER_RGB_565);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        glide.register(RetrofitStream.class, InputStream.class, new RetrofitStreamLoader.Factory());
    }
}

6) 在AndroidManifest.xml中添加关于创建的RetrofitGlideModule的元数据

<application...>
<meta-data
        android:name="<package>.RetrofitGlideModule"
        android:value="GlideModule" />
</application>

现在您可以通过以下方式下载图片:

Call<ResponseBody> call = retrofit.getImage(cacheableRequest);
Glide.with(context).load(new RetrofitStream(call, cacheableRequest)).into(imageView);

关于android - 如何通过 HTTP POST 方法使用 Glide 下载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41342371/

相关文章:

java - 让代码在 x 秒后执行 - Java、Android

安卓区域监控?

java - 如何将 GlideBitmapDrawable 相互转换为 BitmapDrawable

java - glide 不从存储 firebase 加载图片

android - Imageloader 类在图库中创建 lazylist 文件夹。如何避免

android - 使用RxJava在主线程室中执行删除

android - 我们可以看到我自己的 Android 应用程序的 Activity 堆栈吗?

android - Glide 4.7.1 占位符未加载

javascript - 提高 JavaScript 速度

html - 图像速度太慢,当文档完成加载时它们不会出现在页面上