RecyclerView and asynchronous loading

I have a little problem. Need to push in the right direction. I am making a video editor such as Vine and / or instagram. Where they show the timeline with screenshots from the video enter image description here

It simply adds more images depending on the length of the video. What I did for my application was that I added recyclerView. This recyclerview has an adapter that calls the following onBindViewHolder function each time

  public Bitmap getFrameFromCurrentVideo(int seconds) {
    Bitmap bitmap = null;
    if(mMediaMetadataRetriever != null) {
      bitmap = mMediaMetadataRetriever.getFrameAtTime(seconds * 1000000, MediaMetadataRetriever.OPTION_CLOSEST);
    }
    return bitmap;
  }

This works, and it adds the correct number of images that I want. But the problem is that it is too heavy for the user interface thread. Because recyclerView recycles everything. Then he stops every time he needs to get a frame.

So, I thought that I needed to do some asynchronous task and then cache the images. But I read that AsyncTask is not recommended for recycler views, as it is being recycled.

So what should I do to improve performance? Any good idea?

+4
source share
1 answer

This is what I did to solve my problem. I created an asynchronous task and a memory cache in my result.

, . . . async . , , .

, , . . .

  @Override
  public void onBindViewHolder(PostVideoRecyclerViewHolder holder, int position) {
    holder.mImageView.getLayoutParams().width = mScreenWidth / mMaxItemsOnScreen;
    holder.mImageView.setImageDrawable(null);
    int second = position * 3 - 3;
    String TAG = String.valueOf(second);
    holder.mImageView.setTag(TAG);

    Bitmap bitmap = mFragment.getBitmapFromMemCache(TAG);
    if(bitmap == null) {
      PostVideoBitmapWorkerTask task = new PostVideoBitmapWorkerTask(holder.mImageView, TAG, mFragment);
      task.execute(second);
    }
    else {
      holder.mImageView.setImageBitmap(bitmap);
    }
  }

AsyncTask

public class PostVideoBitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
  private ImageView mImageView;
  private String TAG;
  private PostVideoFeedFragment mFragment;

  public PostVideoBitmapWorkerTask(ImageView imageView, String TAG, PostVideoFeedFragment fragment) {
    mImageView = imageView;
    this.TAG = TAG;
    mFragment = fragment;
  }

  @Override
  protected Bitmap doInBackground(Integer... params) {
    Bitmap bitmap = mFragment.getFrameFromCurrentVideo(params[0]);
    mFragment.addBitmapToCache(TAG,bitmap);
    return bitmap;
  }

  @Override
  protected void onPostExecute(Bitmap bitmap) {
    if(mImageView.getTag().toString().equals(TAG)) {
      mImageView.setImageBitmap(bitmap);
    }
  }
}

  public void addBitmapToCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
      mMemoryCache.put(key, bitmap);
    }
  }

  public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
  }

https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html,

https://developer.android.com/reference/android/os/AsyncTask.html asyncTask

+5

Source: https://habr.com/ru/post/1649205/


All Articles