Использование Glide v4 для предварительной загрузки изображений для RecyclerView в AsyncTask - PullRequest
0 голосов
/ 18 мая 2018

Я использую Glide v4 для удаленной загрузки и кэширования изображений.Я хочу предварительно загрузить изображения RecyclerView с Glide и другие данные (например, текст) с сервера в AsyncTask, отображая индикатор выполнения в макете вместо RecyclerView.Я сделал это успешно, используя

Drawable drawable = Glide.with(context)
.load(url)
.submit()
.get();

, а затем сохраняя в памяти Drawables, применяя его к ImageView в OnBindViewHolder ():

imageView.setImageDrawable(drawable);

Hovewer, я понимаю, что хранение Drawablesв памяти неэффективно, кеширование диска также не работает, поэтому я решил попробовать загрузить все изображения в кеш диска в AsyncTask следующим образом:

Glide.with(context)
.downloadOnly()    
.load(url)
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.DATA))
.submit();

, а затем извлечь их в OnBindViewHolder () по:

Glide.with(context)
.load(url)
.apply(new RequestOptions().onlyRetrieveFromCache(true))
.into(imageView);

Но предварительная загрузка в AsyncTask или загрузка из дискового кэша не работает, в результате чего изображения загружаются из Интернета после завершения AsyncTask.Журнал:

Glide: загрузка не удалась для http://image.tmdb.org/t/p/w600_and_h900_bestv2/h5n8B12WoY1UAZjzSVEup4vsoBw.jpg с размером [255x255], класс com.bumptech.glide.load.engine.GlideException: не удалось загрузить ресурс

Начиная с здесь , я пришел к выводу, что загрузка изображения из дискового кэша не удалась, потому что размер представления и размер предварительно загруженного изображения различны.Из документации Glide я предположил, что для автоматического определения размера ImageView мне нужно предварительно загрузить изображение в необходимый ImageView и получить объект Target (но я не уверен в этом) на

Target<Drawable> target = Glide.with(context)
.load(url)
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.DATA))
.into(imageView);

, а затемполучить изображение из кэша в OnBindViewHolder () с помощью

Glide.with(context)
.load(url)
.apply(new RequestOptions().onlyRetrieveFromCache(true))
.into(target);

Но я не знаю, как и когда передавать ссылки на ViewHolder ImageView RecyclerView в doInBackground () AsyncTask, и является ли хорошей практикой передавать представления вфоновые темы?

Или, может быть, есть более четкое решение для фонового кэширования и последующего извлечения?

1 Ответ

0 голосов
/ 18 мая 2018

используйте IntentService для загрузки образа.

public class LoadImage extends IntentService {
private CommonData common;
private final String TAG = "LoadAvatar";

@Override
protected void onHandleIntent(@Nullable Intent intent) {
    String data = intent.getStringExtra("data");
    try {
        JSONObject jsonObject = new JSONObject(data);
        JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("res");
        for (int i = 0; i < jsonArray.length(); i++) {

                JSONObject jObj = jsonArray.getJSONObject(i);
                FutureTarget<File> future = Glide.with(this).load(jObj.getString("url")).downloadOnly(400, 400);
                try {
                    future.get();
                    //stopSelf();
                    break;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    stopSelf();
                    break;
                } catch (ExecutionException e) {
                    e.printStackTrace();
                    stopSelf();
                    break;
                }


        }
    } catch (Exception e) {
       e.printStackTrace();
        stopSelf();
    }
}

}

и вызовите службу намерений при запуске.

  Intent i = new Intent(this, LoadAvatar.class);
  i.putExtra("data", data);
  startService(i);
...