使用LruCache解决RecyclerView滑动卡顿问题
最近自己在做一个本地媒体的APP,在做完音乐列表的时候,发现滑动会比较卡顿,没有丝毫流畅的感觉,通过调试打印时间戳,发现是在获取封面的时候,比较耗时,因为一开始做法是在每次滑动列表的时候,再使用MediaMetadataRetriever和BitmapFactory去获取一次封面,因此比较费时间。在了解了卡顿的问题后,通过查阅资料,发现有LruCache这个缓存的类,可以将音乐的封面以内存的方式,暂时存储在内存当中,使用的时候,再拿出来即可。下面我分享一下我的解决方法。
1、创建MediaCoverCacheUtil类,并设置为单例模式
public static MediaCoverCacheUtil getInstance(Context context){
if (mInstance == null){
synchronized (MediaCoverCacheUtil.class){
if (mInstance == null){
mContext = context.getApplicationContext();
mInstance = new MediaCoverCacheUtil();
}
}
}
return mInstance;
}
2、在构造方法中初始化LruCache类
public MediaCoverCacheUtil(){
int maxSize = (int) (Runtime.getRuntime().maxMemory() / 4);
mLruCache = new LruCache<String,Bitmap>(maxSize){
@Override
protected int sizeOf(@NonNull String key, @NonNull Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
}
3、设置绑定封面的方法
在这个地方当中,通过歌曲文件的路径来绑定歌曲的封面,没有封面的歌曲文件,我传入了一个默认的封面。
public void bindMusicBitmap(String path){
if ( !TextUtils.isEmpty(path) && mLruCache.get(path) == null){
Log.d(TAG,"bindMusicBitmap new :path = "+path);
Bitmap bitmap = musicInfoUtil.getSongCover(path);
if (bitmap != null){
mLruCache.put(path,bitmap);
}else{
mLruCache.put(path,musicInfoUtil.changeDrawableToBitmap(mContext.getDrawable(R.drawable.default_music)));
}
}
}
4、设置获取封面的方法
通过歌曲文件的路径,获取对应的封面,如果是没有保存过封面的歌曲,则直接返回null。
public Bitmap getLruCacheBitmap(String path){
if (mLruCache.get(path) == null){
Log.d(TAG,"getLruCacheBitmap == null : path = "+path);
return null;
}
Log.d(TAG,"getLruCacheBitmap != null : path = "+path);
return mLruCache.get(path);
}
5、绑定封面
MediaCoverCacheUtil.getInstance(mContext).bindMusicBitmap(path);
6、获取封面显示
Bitmap bitmap = MediaCoverCacheUtil.getInstance(mContext).getLruCacheBitmap(path);
在尝试了上面的方法之后,发现,确实对前面的卡顿有了非常大的改善,现在列表滑动起来非常丝滑,特此分享给大家,谢谢。有错误的地方,请大家指正,谢谢!