:视频播放器与Handler 完美调用
2013-10-30 21:53
441 查看
Handler之消息循环
Handler,Looper和MessageQueue是属于一个线程内部的数据,但是它提供给外部线程访问的接口,Handler就是公开给外部线程,与线程通讯的接口。换句话说,这三个东西都是用来线程间通讯用的(ITC--InterThreadCommunication),与进行间通讯(IPC--InterProcessCommunication)的消息队列msgque的核心思想是一致的。MessageQueue是相对较底层的,较少直接使用,Looper和Handler就是专门用来操作底层MessageQueue的。
还有一个重要的数据结构是通讯的基本元素,就是消息对象(Message),Message从来不单独使用,它都是跟随Handler来使用的。具体方法可以参考文档,但需要注意的是同一个消息对象不能发送二次,否则会有AndroidRuntimeException:{what=1000when=-15msobj=..}Thismessageisalreadyinuse."。每次发送消息前都要通过Message.obtain()来获取新的对象,或者,对于不需要传送额外数据的直接发送空消息就好Handler.sendEmptyMessage(int)。另外也需要注意消息对象是不能手动回收的,也就是说你不能调用Message.recycle()来释放一个消息对象,因为当该对象被从队列中取出处理完毕后,MessageQueue内部会自动的去做recycle()。这个理解起来也很容易,因为发送一个消息到消息队列后,消息什么时候会被处理,对于应用程序来讲是不知道的,只有MessageQueue才会知道,所以只能由MessageQueue来做回收释放的动作。
因为Handler是用于操作一个线程内部的消息队列的,所以Handler必须依附于一个线程,而且只能是一个线程。换句话说,你必须在一个线程内创建Handler,同时指定Handler的回调handlerMessage(Messagemsg)。
Handler主要有二个用途,一个是用于线程内部消息循环;另外一个就是用于线程间通讯。
Handler的基本用法可以参考
用于线程内部消息循环
主要是用作在将来定时做某个动作,或者循环性,周期性的做某个动作。主要的接口就是importandroid.media.MediaPlayer;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.app.Activity;
importandroid.util.Log;
importandroid.view.Menu;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.ProgressBar;
publicclassMainActivityextendsActivity{
protectedstaticfinalStringTAG="MainActivity";
privatestaticfinalintMEDIA_PLAYER_READY=0;
privatestaticfinalintREFRESH_PROGRESS=1;
privateButtonmStart;
privateButtonmStop;
privateButtonmPause;
privateSurfaceHoldermSurfaceHolder;
privateProgressBarmProgressBar;
privateSurfaceViewmDisplay;
privateMediaPlayermMediaPlayer;
privateHandlermMainHandler=newHandler(){
@Override
publicvoidhandleMessage(Messagemsg){
switch(msg.what){
caseMEDIA_PLAYER_READY:
mProgressBar.setMax(mMediaPlayer.getDuration());
mMediaPlayer
.setOnCompletionListener(newMediaPlayer.OnCompletionListener(){
publicvoidonCompletion(MediaPlayermp){
mProgressBar.setProgress(mMediaPlayer
.getDuration());
mMainHandler.removeMessages(REFRESH_PROGRESS);
}
});
mStart.setEnabled(true);
mStop.setEnabled(true);
break;
caseREFRESH_PROGRESS:
intcp=mMediaPlayer.getCurrentPosition();
mProgressBar.setProgress(cp);
intdelay=1000-(cp%1000);
mMainHandler.sendEmptyMessageDelayed(REFRESH_PROGRESS,delay);
break;
default:
break;
}
}
};
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
privatevoidinitView(){
//TODOAuto-generatedmethodstub
mStart=(Button)this.findViewById(R.id.btn_player);
mPause=(Button)this.findViewById(R.id.btn_pause);
mProgressBar=(ProgressBar)this.findViewById(R.id.progressbar);
mStop=(Button)this.findViewById(R.id.btn_stop);
mStart.setOnClickListener(newbuttonListenner());
mPause.setOnClickListener(newbuttonListenner());
mStop.setOnClickListener(newbuttonListenner());
mStop.setEnabled(false);
mDisplay=(SurfaceView)findViewById(R.id.surfaceview);
mSurfaceHolder=mDisplay.getHolder();
mSurfaceHolder.setFixedSize(mDisplay.getWidth(),mDisplay.getHeight());
//Donotbelievethedocument,setTypeisnecessary,otherwise,video
//won'tplaycorrectly
// mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_HARDWARE);
newThread(newRunnable(){
publicvoidrun(){
try{
Log.e(TAG,"Threadisruning");
mMediaPlayer=MediaPlayer.create(getApplication(),
R.raw.test);
Log.e(TAG,"Threadisruning");
mMediaPlayer.setDisplay(mSurfaceHolder);
mMainHandler.sendEmptyMessage(MEDIA_PLAYER_READY);
}catch(IllegalArgumentExceptione){
Log.e(TAG,"caughtexceptione",e);
}catch(SecurityExceptione){
Log.e(TAG,"caughtexceptione",e);
}catch(IllegalStateExceptione){
Log.e(TAG,"caughtexceptione",e);
}
}
}).start();
}
privateclassbuttonListennerimplementsOnClickListener{
@Override
publicvoidonClick(Viewv){
switch(v.getId()){
caseR.id.btn_player:
mMediaPlayer.start();
mMainHandler.sendEmptyMessage(REFRESH_PROGRESS);
break;
caseR.id.btn_pause:
mMainHandler.removeMessages(REFRESH_PROGRESS);
mMediaPlayer.pause();
break;
caseR.id.btn_stop:
break;
default:
break;
}
}
}
@Override
protectedvoidonDestroy(){
super.onDestroy();
mMainHandler.removeMessages(REFRESH_PROGRESS);
if(mMediaPlayer!=null){
mMediaPlayer.release();
}
}
publicbooleanonCreateOptionsMenu(Menumenu){
//Inflatethemenu;thisaddsitemstotheactionbarifitispresent.
getMenuInflater().inflate(R.menu.main,menu);
returntrue;
}
}
相关文章推荐
- 各种居中
- 编译schroedinger-1.0.11
- 或许咱们可以打造一个信息共享平台
- 找工作总结-机会往往留给有准备的人
- A* 搜索算法
- 通用hash表
- android表示单位长度的三种方式
- nyoj 19 擅长排列的小明
- redis数据类型之zset(Sorted-Sets)
- 挖掘新的学习方法-专题式
- adb server is out of date. killing...
- 研究下linux下仿qq--eva0.4.1的源码1
- java 关于中文字的输出 输入 和文件操作(对象序列化)
- 解读AbsSeekBar【二】(注释中……)
- ROS的学习(十六)用C++写一个简单的服务器(service)和客户端(client)
- HDU4472_Count
- MySql5.5忘记root密码的解决方法
- Start GitHub
- Centos 6.2 开启 VNC远程桌面
- Dnsmasq之配置