2016-12-27 552 views
2

服務器提供API以通過Post請求加載圖像,其主體看起來像如何使用Glide通過HTTP POST方法下載圖像

{ 
"image_id": someId, 
"session_id": "someId" 
} 
響應 - 流。
如何使用Glide通過HTTP POST方法下載圖像?

+0

什麼是圖片ID? –

+0

理想情況下,服務器必須發送**圖片url **作爲** GET **請求,然後您必須將該URL傳遞給Glide。希望您使用Volley提出請求,如果您使用兩個異步請求,一個用於內容,另一個用於圖像,則應用性能會提高 –

回答

2

算法使用滑翔經由HTTP POST方法&改造2加載圖像:

1)創建界面,這應該通過經由HTTP POST方法用於圖像加載所有請求來實現:

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的一個實現,它允許配置滑翔

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)增加關於創建RetrofitGlideModule元數據在AndroidManifest.xml

<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); 
0

首先,你必須創建一個模型對象針對上述響應

Example : 

    import android.os.Parcel; 
    import android.os.Parcelable; 

    public class Movies implements Parcelable { 
     private String poster_path; 
     private String id; 

     public Movies() { 
     } 

     private Movies(Parcel in) { 
      poster_path = in.readString(); 
      id = in.readString(); 
     } 

     public static final Creator<Movies> CREATOR = new Creator<Movies>() { 
      @Override 
      public Movies createFromParcel(Parcel in) { 
       return new Movies(in); 
      } 

      @Override 
      public Movies[] newArray(int size) { 
       return new Movies[size]; 
      } 
     }; 

     public String getPoster_path() { 
      return poster_path; 
     } 

     public void setPoster_path(String poster_path) { 
      this.poster_path = poster_path; 
     } 

     public String getId() { 
      return id; 
     } 

     public void setId(String id) { 
      this.id = id; 
     } 


     @Override 
     public int describeContents() { 
      return 0; 
     } 

     @Override 
     public void writeToParcel(Parcel dest, int flags) { 
      dest.writeString(poster_path); 
      dest.writeString(id); 
     } 
    } 

一旦模型是從我們需要保存這些數據的響應創建。

private void fetchTask(final String movieType) { 

      if (jsonObjectRequest != null) { 
       jsonObjectRequest.cancel(); 
       movies.clear(); 
      } 
      Uri.Builder builder = new Uri.Builder(); 
      builder.scheme("https") 
        .authority("api.themoviedb.org") 
        .appendPath("3") 
        .appendPath("movie") 
        .appendPath(movieType) 
        .appendQueryParameter(MOVIE_API_KEY, MOVIE_API_VALUE); 
      String url = builder.build().toString(); 
      jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, new Response.Listener<JSONObject>() { 
       @Override 
       public void onResponse(JSONObject response) { 

        try { 
         JSONArray jsonArray = response.getJSONArray(MovieModelConstants.MOVIE_RESULTS); 
         for (int i = 0; i < jsonArray.length(); i++) { 
          JSONObject jsonObject = jsonArray.getJSONObject(i); 
          Movies data = new Movies(); 
          data.setPoster_path(jsonObject.getString(MOVIE_POSTER_PATH)); 
          data.setId(jsonObject.getString(MOVIE_ID)); 
          movies.add(data); 
         } 
         moviesAdapter = new MoviesAdapter(movies); 
         moviesAdapter.setItemClickListener(clickListener); 
         recyclerViewMovies.setAdapter(moviesAdapter); 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 

       } 
      }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 

        Toast.makeText(getContext(), getString(R.string.errorMessage), Toast.LENGTH_SHORT); 

       } 
      }); 
      Volley.newRequestQueue(getContext()).add(jsonObjectRequest); 
     } 
    } 

在你需要的適配器加載有基於位置

Picasso.with(holder.mMovieItem.getContext()).load(generateUrlForPoster(String.valueOf(data.get(position).getPoster_path()))).into(holder.mMovieItem); 
0

有一個在滑翔沒有這樣的方法,該方法接收發布請求的URL。

所以,您必須使用HTTPUrlConnection從請求中獲取bytes [],然後使用Glide將此字節[]加載到imageView中。

Glide.with(context).load(byteArr).into(imageView);