RecyclerView 和异步加载
RecyclerView and async Loading
我有一个小问题。需要朝着正确的方向推动。
我正在做一个像 Vine and/or instagram 这样的视频编辑器。他们在哪里显示带有视频屏幕截图的时间线
它只是根据视频时长添加更多图片。我为我的应用程序所做的是添加了一个 recyclerView。这个recyclerview有一个adapter,每次onBindViewHolder
调用下面的函数
public Bitmap getFrameFromCurrentVideo(int seconds) {
Bitmap bitmap = null;
if(mMediaMetadataRetriever != null) {
bitmap = mMediaMetadataRetriever.getFrameAtTime(seconds * 1000000, MediaMetadataRetriever.OPTION_CLOSEST);
}
return bitmap;
}
这有效,它添加了我想要的适当数量的图像。但问题是它在UI线程上太重了。由于 recyclerView 正在回收一切。然后每次必须获取帧时它都会滞后。
所以我想我必须做一些异步任务然后缓存图像。但我读到的是,不建议将 AsyncTask 用于回收站视图,因为它会回收。
那么我应该怎么做才能提高性能呢?有什么好主意吗?
这就是我解决问题的方法。
我创建了异步任务和内存缓存我的结果。
我的适配器检查图像是否已经存在。如果是的话。然后我们跳过做后台工作。否则我会执行异步任务并尝试加载图像。我们还标记视图以防用户在任务未完成时滚动。
这有助于我们检查标签是否与任务所具有的不同。如果相同。然后我们就可以安全地将正确的图像放入图像视图中了。
来自我的适配器的片段
@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);
}
}
我的异步任务class
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);
}
}
}
我片段的片段class
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 的
我有一个小问题。需要朝着正确的方向推动。
我正在做一个像 Vine and/or instagram 这样的视频编辑器。他们在哪里显示带有视频屏幕截图的时间线
它只是根据视频时长添加更多图片。我为我的应用程序所做的是添加了一个 recyclerView。这个recyclerview有一个adapter,每次onBindViewHolder
调用下面的函数 public Bitmap getFrameFromCurrentVideo(int seconds) {
Bitmap bitmap = null;
if(mMediaMetadataRetriever != null) {
bitmap = mMediaMetadataRetriever.getFrameAtTime(seconds * 1000000, MediaMetadataRetriever.OPTION_CLOSEST);
}
return bitmap;
}
这有效,它添加了我想要的适当数量的图像。但问题是它在UI线程上太重了。由于 recyclerView 正在回收一切。然后每次必须获取帧时它都会滞后。
所以我想我必须做一些异步任务然后缓存图像。但我读到的是,不建议将 AsyncTask 用于回收站视图,因为它会回收。
那么我应该怎么做才能提高性能呢?有什么好主意吗?
这就是我解决问题的方法。 我创建了异步任务和内存缓存我的结果。
我的适配器检查图像是否已经存在。如果是的话。然后我们跳过做后台工作。否则我会执行异步任务并尝试加载图像。我们还标记视图以防用户在任务未完成时滚动。
这有助于我们检查标签是否与任务所具有的不同。如果相同。然后我们就可以安全地将正确的图像放入图像视图中了。
来自我的适配器的片段
@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);
}
}
我的异步任务class
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);
}
}
}
我片段的片段class
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 的