2016-12-27 2 views
2

Сервер предоставляет API для загрузки изображения через запрос на публикацию, корпус которого выглядит как Как загрузить изображение с помощью Glide через HTTP POST-метод

{ 
"image_id": someId, 
"session_id": "someId" 
} 
Response - stream.
Как загрузить изображение с помощью метода Glide через HTTP POST?

+0

что такое ID изображения? –

+0

идеально сервер должен отправить ** url ** ** как ** GET ** запрос, а затем вы должны передать этот url для Glide. надеясь, что вы используете Volley для выполнения запроса, производительность вашего приложения будет улучшена, если вы используете два асимхронных запроса один для контента, а другой для изображения –

ответ

2

Алгоритм для загрузки изображений с помощью Glide & Ретрофита 2 через метод HTTP POST:

1) Создание интерфейса, который должен быть реализован с помощью всех запросов для загрузки изображений с помощью метода HTTP POST:

public interface CacheableRequest { 
    String getCacheKey(); 
} 

2) Создание модели для загрузки, которая будет использоваться в качестве параметра для Glide.with (контекста) .load (модель):

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) Добавить мета-данные о созданной 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

Там нет такого метода в Glide, которые получают сообщение с запросом URL.

Итак, вам нужно получить байты [] с помощью HTTPUrlConnection, а затем загрузить эти байты [] в imageView с помощью Glide.

Glide.with(context).load(byteArr).into(imageView); 
Смежные вопросы