这个使用起来并不难,但需要注意一点的是,线程内部消息循环并不是并发处理,也就是所有的消息都是在Handler所属的线程内处理的,所以虽然你用post(Runnable r),发给MessageQueue一个Runnable,但这并不会创建新的线程来执行,处理此消息时仅是调用r.run()。(想要另起线程执行,必须把Runnable放到一个Thread中)。
这里用一个实例来展示主线程通过Handler与后台线程进行通信,并且主线程用Handler来实现循环时序。
播放一个视频,线程用于创建和初始化MediaPlayer,初始化好后会通过主线程的Handler告诉主线程,然后主线程可以播放视频,在播放过程中通过sendMessageDelayed()来实现播放进度的不断更新:
public class HandlerSimpleDemo extends Activity { protected static final String TAG = "HandlerSimpleDemo"; private static final int MEDIA_PLAYER_READY = 0; private static final int REFRESH_PROGRESS = 1; private Button mStart; private Button mStop; 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; } } }; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.handler_simple_demo); mStart = (Button) findViewById(R.id.handler_simple_start); mStart.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { mMediaPlayer.start(); mMainHandler.sendEmptyMessage(REFRESH_PROGRESS); } }); mStart.setEnabled(false); mStop = (Button) findViewById(R.id.handler_simple_stop); mStop.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { mMainHandler.removeMessages(REFRESH_PROGRESS); mMediaPlayer.pause(); } }); mStop.setEnabled(false); mProgressBar = (ProgressBar) findViewById(R.id.handler_simple_progress); mDisplay = (SurfaceView) findViewById(R.id.handler_simple_display); 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); new Thread(new Runnable() { public void run() { try { mMediaPlayer = MediaPlayer.create(getApplication(), R.raw.flug); 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(); } @Override protected void onDestroy() { super.onDestroy(); mMainHandler.removeMessages(REFRESH_PROGRESS); if (mMediaPlayer != null) { mMediaPlayer.release(); } } }