填坑一:
viewpager+fragment(3个fragment),其中有一个fragment内有listview,listeview内含有播放视频控件时,进入到界面会闪屏一次。
原因是:listview内item的视频控件在fragment,fragment在activity是动态添加的,不会随着activity的初始化而刷新,只有在加载完fragment的时候加载刷新,所有会出现一次闪屏。这个时候只要在activityde xml界面内添加一段代码即可:
<SurfaceView
android:layout_width="0dp"
android:layout_height="0dp" />
填坑二:
从上一个坑爬出,继续下一个,listview内item视频控件需要显示缩略图,这里播放的是网络视频,所有是由url的,具体实现代码是:
public Bitmap createVideoThumbnail(String url, int width, int height) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
int kind = MediaStore.Video.Thumbnails.MINI_KIND;
try {
if (Build.VERSION.SDK_INT >= 14) {
retriever.setDataSource(url, new HashMap<String, String>());
} else {
retriever.setDataSource(url);
}
bitmap = retriever.getFrameAtTime();
} catch (IllegalArgumentException ex) {
// Assume this is a corrupt video file
} catch (RuntimeException ex) {
// Assume this is a corrupt video file.
} finally {
try {
retriever.release();
} catch (RuntimeException ex) {
// Ignore failures while cleaning up.
}
}
if (kind == MediaStore.Images.Thumbnails.MICRO_KIND && bitmap != null) {
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
}
return bitmap;
}
但是会出现卡顿的情况,因为这里是listview在使用,而且
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
1.创建一个子线程:
static class CreateVideoThumbnail extends Thread { private String url; private Handler handler; public CreateVideoThumbnail(String url, Handler handler) { this.url = url; this.handler = handler; } @Override public void run() { super.run(); handler.obtainMessage(0, createVideoThumbnail(url, 300, 300)).sendToTarget(); } public Bitmap createVideoThumbnail(String url, int width, int height) { Bitmap bitmap = null; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); int kind = MediaStore.Video.Thumbnails.MINI_KIND; try { if (Build.VERSION.SDK_INT >= 14) { retriever.setDataSource(url, new HashMap<String, String>()); } else { retriever.setDataSource(url); } bitmap = retriever.getFrameAtTime(); } catch (IllegalArgumentException ex) { // Assume this is a corrupt video file } catch (RuntimeException ex) { // Assume this is a corrupt video file. } finally { try { retriever.release(); } catch (RuntimeException ex) { // Ignore failures while cleaning up. } } if (kind == MediaStore.Images.Thumbnails.MICRO_KIND && bitmap != null) { bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height, ThumbnailUtils.OPTIONS_RECYCLE_INPUT); } return bitmap; } }2.子线程把耗时操作完成,通知ui线程,代码如下:
Handler handler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (ok) { ivThumb.setImageBitmap((Bitmap) msg.obj); ok = false; } } };3.现在准备工作完成,去调用子线程,代码:
t = new CreateVideoThumbnail(url, handler); t.start();4.还没完成,因为这是是listview在用,listview有复用功能,而且,你的子线程会一直在线程池中,你必须在上一个view消失的时候把线程取消掉,要不然会有2种情况出现,(1)报错(2)现在view使用的还是上一个view的数据,所有要先reset,在你视频播放之前使用代码:
public void reset() { if (t != null) { t.interrupt(); } handler.removeMessages(0); ok = true; }5.最后考虑到生命周期,在view消失的时候再reset一下,虽然有时不考虑生命周期不会出现问题,但是有可能会把你的内存往上调一下(就是占用内存),有时它会直接报错。这里小分队提示,最好去考虑下生命周期更好。