zoukankan      html  css  js  c++  java
  • :视频播放器与Handler 完美调用

    Handler之消息循环

     


    Handler是用于操作线程内部的消息队列的类。这有点绕,没关系,我们慢慢的来讲。前面Looper一篇讲到了Looper是用于给线程创建消息队列用的,也就是说Looper可以让消息队列(MessageQueue)附属在线程之内,并让消息队列循环起来,接收并处理消息。但,我们并不直接的操作消息队列,而是用Handler来操作消息队列,给消息队列发送消息,和从消息队列中取出消息并处理。这就是Handler的职责。
    Handler,Looper和MessageQueue是属于一个线程内部的数据,但是它提供给外部线程访问的接口,Handler就是公开给外部线程,与线程通讯的接口。换句话说,这三个东西都是用来线程间通讯用的(ITC--Inter Thread Communication),与进行间通讯(IPC--Inter Process Communication)的消息队列msgque的核心思想是一致的。MessageQueue是相对较底层的,较少直接使用,Looper和Handler就是专门用来操作底层MessageQueue的。
    还有一个重要的数据结构是通讯的基本元素,就是消息对象(Message),Message从来不单独使用,它都是跟随Handler来使用的。具体方法可以参考文档,但需要注意的是同一个消息对象不能发送二次,否则会有AndroidRuntimeException: { what=1000 when=-15ms obj=.. } This message is already in use."。每次发送消息前都要通过Message.obtain()来获取新的对象,或者,对于不需要传送额外数据的直接发送空消息就好Handler.sendEmptyMessage(int)。另外也需要注意消息对象是不能手动回收的,也就是说你不能调用Message.recycle()来释放一个消息对象,因为当该对象被从队列中取出处理完毕后,MessageQueue内部会自动的去做recycle()。这个理解起来也很容易,因为发送一个消息到消息队列后,消息什么时候会被处理,对于应用程序来讲是不知道的,只有MessageQueue才会知道,所以只能由MessageQueue来做回收释放的动作。
    因为Handler是用于操作一个线程内部的消息队列的,所以Handler必须依附于一个线程,而且只能是一个线程。换句话说,你必须在一个线程内创建Handler,同时指定Handler的回调handlerMessage(Message msg)。
    Handler主要有二个用途,一个是用于线程内部消息循环; 另外一个就是用于线程间通讯。
    Handler的基本用法可以参考文档,说的还是比较清楚的。

    用于线程内部消息循环

    主要是用作在将来定时做某个动作,或者循环性,周期性的做某个动作。主要的接口就是

    package com.example.handler_simple;
    
    import android.media.MediaPlayer;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.app.Activity;
    import android.util.Log;
    import android.view.Menu;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ProgressBar;
    
    public class MainActivity extends Activity {
    
    	protected static final String TAG = "MainActivity";
    	private static final int MEDIA_PLAYER_READY = 0;
    	private static final int REFRESH_PROGRESS = 1;
    
    	private Button mStart;
    	private Button mStop;
    	private Button mPause;
    	private SurfaceHolder mSurfaceHolder;
    	private ProgressBar mProgressBar;
    	private SurfaceView mDisplay;
    	private MediaPlayer mMediaPlayer;
    
    	private Handler mMainHandler = new Handler() {
    		@Override
    		public void handleMessage(Message msg) {
    			switch (msg.what) {
    			case MEDIA_PLAYER_READY:
    				mProgressBar.setMax(mMediaPlayer.getDuration());
    				mMediaPlayer
    						.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    							public void onCompletion(MediaPlayer mp) {
    								mProgressBar.setProgress(mMediaPlayer
    										.getDuration());
    								mMainHandler.removeMessages(REFRESH_PROGRESS);
    							}
    						});
    				mStart.setEnabled(true);
    				mStop.setEnabled(true);
    				break;
    			case REFRESH_PROGRESS:
    				int cp = mMediaPlayer.getCurrentPosition();
    				mProgressBar.setProgress(cp);
    				int delay = 1000 - (cp % 1000);
    				mMainHandler.sendEmptyMessageDelayed(REFRESH_PROGRESS, delay);
    				break;
    			default:
    				break;
    			}
    		}
    	};
    
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		initView();
    	}
    
    	private void initView() {
    		// TODO Auto-generated method stub
    
    		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(new buttonListenner());
    		mPause.setOnClickListener(new buttonListenner());
    		mStop.setOnClickListener(new buttonListenner());
    		mStop.setEnabled(false);
    		mDisplay = (SurfaceView) findViewById(R.id.surfaceview);
    		mSurfaceHolder = mDisplay.getHolder();
    		mSurfaceHolder.setFixedSize(mDisplay.getWidth(), mDisplay.getHeight());
    		// Do not believe the document, setType is necessary, otherwise, video
    		// won't play correctly
    //		mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    //		mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_HARDWARE);
    		new Thread(new Runnable() {
    			public void run() {
    				try {
    					Log.e(TAG, "Thread is runing");
    					mMediaPlayer = MediaPlayer.create(getApplication(),
    							R.raw.test);
    					Log.e(TAG, "Thread is runing");
    					mMediaPlayer.setDisplay(mSurfaceHolder);
    					mMainHandler.sendEmptyMessage(MEDIA_PLAYER_READY);
    				} catch (IllegalArgumentException e) {
    					Log.e(TAG, "caught exception e", e);
    				} catch (SecurityException e) {
    					Log.e(TAG, "caught exception e", e);
    				} catch (IllegalStateException e) {
    					Log.e(TAG, "caught exception e", e);
    				}
    			}
    		}).start();
    	}
    
    	private class buttonListenner implements OnClickListener {
    
    		@Override
    		public void onClick(View v) {
    
    			switch (v.getId()) {
    			case R.id.btn_player:
    				  mMediaPlayer.start();  
    			        mMainHandler.sendEmptyMessage(REFRESH_PROGRESS);  
                  
    				break;
    			case R.id.btn_pause:
    				 mMainHandler.removeMessages(REFRESH_PROGRESS);  
    			        mMediaPlayer.pause();  
    
    				break;
    			case R.id.btn_stop:
    
    				break;
    
    			default:
    				break;
    			}
    
    		}
    	}
    
    	@Override
    	protected void onDestroy() {
    		super.onDestroy();
    		mMainHandler.removeMessages(REFRESH_PROGRESS);
    		if (mMediaPlayer != null) {
    			mMediaPlayer.release();
    		}
    	}
    
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.main, menu);
    		return true;
    	}
    
    }
    


     

  • 相关阅读:
    修改hosts文件
    什么时候集合不可以插入空值
    OL2中实现百度地图ABCD marker的效果
    OL3实现多图联动
    Arcgis for javascript实现百度地图ABCD marker的效果
    OL记载Arcgis Server切片
    postgis常用函数介绍(二)
    postgis常用函数介绍(一)
    共享个地图控件的样式
    OpenLayers3基础教程——OL3 介绍interaction
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3397883.html
Copyright © 2011-2022 走看看