您的位置:首页 > 移动开发 > Android开发

android开发杂记一

2017-01-07 17:25 369 查看

填坑一:

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();


是一个耗时操作,所有我们的第一个反应是把它加在子线程中实现,UI线程显示,代码如下:
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一下,虽然有时不考虑生命周期不会出现问题,但是有可能会把你的内存往上调一下(就是占用内存),有时它会直接报错。这里小分队提示,最好去考虑下生命周期更好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: