To resolve this issue, I have made a class VideoThumbLoader
. It asynchronously generated Bitmap and passes it to adapter. So that main benefit is that the whole process is being handled in background thread.
The code for class is as below:
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.support.v4.util.LruCache;
import android.widget.ImageView;
public class VideoThumbLoader {
private LruCache<String, Bitmap> lruCache;
@SuppressLint("NewApi")
public VideoThumbLoader() {
int maxMemory = (int) Runtime.getRuntime().maxMemory();// obtain maximum
// memory to run
int maxSize = maxMemory / 4;// get cache memory size 35
lruCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
// this will be called when the cache deposited in each
return value.getByteCount();
}
};
}
public void addVideoThumbToCache(String path, Bitmap bitmap) {
if (getVideoThumbToCache(path) == null && bitmap != null) {
lruCache.put(path, bitmap);
}
}
public Bitmap getVideoThumbToCache(String path) {
return lruCache.get(path);
}
public void showThumbByAsynctack(String path, ImageView imgview) {
if (getVideoThumbToCache(path) == null) {
// asynchronous loading
new MyBobAsynctack(imgview, path).execute(path);
} else {
imgview.setImageBitmap(getVideoThumbToCache(path));
}
}
class MyBobAsynctack extends AsyncTask<String, Void, Bitmap> {
private ImageView imgView;
private String path;
public MyBobAsynctack(ImageView imageView, String path) {
this.imgView = imageView;
this.path = path;
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(params[0],
MediaStore.Video.Thumbnails.MINI_KIND);
// provide
if (getVideoThumbToCache(params[0]) == null) {
addVideoThumbToCache(path, bitmap);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imgView.getTag().equals(path)) {// through Tag can be bound
// pictures address and
// imageView, this address
// Listview loading the image
// dislocation solution
imgView.setImageBitmap(bitmap);
}
}
}
}
And from adapter side, simply call:
private VideoThumbLoader mVideoThumbLoader = new VideoThumbLoader();
imageThumbnail.setTag(videoValues.get(position).getFile()
.getAbsolutePath());// binding imageview
imageThumbnail.setImageResource(R.drawable.videothumb); //default image
mVideoThumbLoader.showThumbByAsynctack(videoValues.get(position)
.getFile().getAbsolutePath(), imageThumbnail);
P.S: One important thing I had taken a note of was, due to asynchronous downloading of bitmap, there were few cases where thumbnails tend to mix up. So I have tagged the imageview with file path. This way I will have the exact thumbnail for the image.