一个多月前在做影音播放器时遇到一个问题,就是在视频列表中显示每个视频第一帧,第一帧是显示出来了,可是滑动的时候出问题了,严重卡顿啊!!!一开始想的是要对图片进行压缩,压缩之后还是卡,然后想到了要开子线程(因为在Android中主线程不能执行耗时操作),把获取视频第一帧的操作放进去,这时候旧问题没有解决,新的问题又出现,图片与视频错位了,查了很多资料最后还是没有很好的解决。 直到今天这个问题终于完美解决了。也就写了ImageLoader类,大概50行代码。我们把获取视频第一帧的操作放入子线程中,根据传入的image(你要显示的在那个位置的图片,也就是Adapter类中 getView方法里通过findViewById获取的),url(视频的路径)
package zkx.com.mobileplayer.util;
/**
* Created by zhang on 2016/10/14.
*/
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.ThumbnailUtils;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
/**
* Created by zhang on 2016/11/27.
*/
public class ImageLoader {
private ImageView mImageView;
private String mUrl;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (mImageView.getTag().equals(mUrl)) {
mImageView.setImageBitmap((Bitmap) msg.obj);
}
}
};
/**
* @param imageView
* @param url
*/
public void showImageByThread(ImageView imageView, final String url) {
mImageView = imageView;
mUrl = url;
new Thread() {
@Override
public void run() {
super.run();
MediaMetadataRetriever media = new MediaMetadataRetriever();
media.setDataSource(url);
Bitmap bitmap = media.getFrameAtTime(3000);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, 100, 100);
Message message = Message.obtain();
message.obj = bitmap;
mHandler.sendMessage(message);
}
}.start();
}
}
然后在你的Adapter类的getView方法里,添上这几句,注意:这里我们iv_icon_video设置了一个唯一的标志tag(通过holder.iv_icon_video.setTag(url) 这段代码,url就是这个唯一的标志tag),相当于给iv_icon_video设置了一个唯一的身份信息,目的就是为避免由于ListView的缓存机制导致图片显示错位,然后调用ImageLoader的showImageByThread方法,传进去holder.iv_icon_video和 url(视频的路径)。然后就是通过showImageByThread方法获取视频第一帧了,我们将获取的bitmap通过Hander发送到了主线程,这样又解决了子线成不能更新UI的问题,然后在handlerMessage方法中处理bitmap,那么我们在Adapter中设置的标志tag就要发挥作用了,我们判断tag是否相同,相同则设置,不同则不处理,那么便解决了错位的问题
//设置默认显示的图片
holder.iv_icon_video.setImageResource(R.drawable.video_default_icon);
String url = videoItem.getPath();
holder.iv_icon_video.setTag(url);
new ImageLoader().showImageByThread(holder.iv_icon_video, url);
还有一点要说的就是在showImageByThread的这两行代码,他们的作用和BaseAdapter里的ViewHolder模式缓存view一样,他们也缓存imageView和url
mImageView = imageView;
mUrl = url;