当前位置: 代码迷 >> Android >> Android学习之路——2.Handler惯用的使用方法
  详细解决方案

Android学习之路——2.Handler惯用的使用方法

热度:33   发布时间:2016-05-01 20:04:17.0
Android学习之路——2.Handler常用的使用方法
所谓的常用的使用方法只是我自己这么认为的。嘻嘻(*^__^*) 好直接上代码。
 package zhenz.exercise;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Looper;import android.os.Message;import android.util.Log;public class ExerciseActivity extends Activity {	/**	 * 缺省构造方法	 */	private Handler mHandler_1 = new Handler();	/**	 * 继承Handler,实现自己的handlerMessage()方法	 */	private Handler mHandler_2 = new Handler() {		@Override		public void handleMessage(Message msg) {			switch (msg.what) {				case 0:					Log.i("mHandler_2",					        "mHandler_2 ,the current Thread's id is:"					                + Thread.currentThread().getId());					break;				case 1:					Log.i("mHandler_2",					        "mHandler_2 ,the current Thread's id is:"					                + Thread.currentThread().getId());					break;			}		}	};	/**	 * 含Handler.Callback参数的构造方法	 */	private Handler mHandler_3 = new Handler(new Handler.Callback() {		@Override		public boolean handleMessage(Message msg) {			Log.i("mHandler_3", "mHandler_3 ,the current Thread's id is:"			        + Thread.currentThread().getId());			return false;		}	});		/**	 * Looper和handlerThread为下面在主线程外使用Handler做准备。	 */	private Looper mLooper;		private HandlerThread handlerThread = new HandlerThread("HandlerThread");	{		handlerThread.start();//一定要先调用start方法		mLooper = handlerThread.getLooper();	}	/**	 * 含Looper参数的构造方法	 */	private Handler mHandler_4 = new Handler(	        mLooper);	/** Called when the activity is first created. */	@Override	public void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.main);		Log.i("Main", "Main,the current Thread's id is:"		        + Thread.currentThread().getId());		// Handler中其他的post方法类似。		boolean done = mHandler_1.postAtTime(new Runnable() {			@Override			public void run() {				Log.i("mHandler_1", "mHandler_1 ,the current Thread's id is:"				        + Thread.currentThread().getId());			}		}, 1000L);		if (done) {//一			Log.i("mHandler_1",			        "Runnable was successfully placed in to the message queue in the mHandler_1");		}		// Handler中其他的sendMessage方法类似		mHandler_2.sendEmptyMessageDelayed(0, 1000L);		// 不同线程通过mHandler_2和主线程通信		Thread thread = new Thread(new Runnable() {			@Override			public void run() {				Log.i("thread", "thread ,the current Thread's id is:"				        + Thread.currentThread().getId());				mHandler_2.sendEmptyMessageDelayed(1, 1000L);			}		});		thread.start();		// 使用Message来传递数据		Message message = Message.obtain(null, 1, 2, 3, "Message 1");		message.setTarget(mHandler_3);		message.sendToTarget();		// Handler中其他的post方法类似,不在主线程中处理事物		boolean can = mHandler_4.postAtTime(new Runnable() {			@Override			public void run() {//二				Log.i("mHandler_4", "mHandler_4 ,the current Thread's id is:"				        + Thread.currentThread().getId());			}		}, 1000L);		if (can) {//三			Log.i("mHandler_4",			        "Runnable was successfully placed in to the message queue in the mHandler_4");		}	}}
由上图的信息可以知道程序处理消息的顺序(有些设置了延时,消息处理的顺序应该是基于时间,具体的我也不太懂啦)以及消息是在哪个线程处理的。
哈哈,提醒一下,看到第二和第四条信息是不同的。
(一)从第一条信息可以知道主线程的id是1。
(二)从第二条信息可以知道了程序已经执行到“一”处了,并且匿名Runnable对象已经成功post到mHandler_1的处理消息队列中(这个消息队列应该是主消息队列),一秒后就大概会执行了。
(三)从第三条信息可以知道程序执行“二”处,这是因为在对象初始化块那里已经调用了HandlerThread对象的start方法,并把这个对象持有的Looper对象传递给了mHandler_4的构造方法。
(四)从第四条信息可以知道程序执行到“三”处,并且匿名Runnable对象已经成功post到mHandler_4的处理消息队列中(这个消息队列应该是HandlerThread对象的消息队列),一秒后就大概会执行了。到这里主线程的程序执行完了,就等着处理在前面入到主线程消息队列的消息了。
(五)从第五条信息可以知道主线程中开启的thread线程执行了,但是为什么是现在执行,这个嘛……我也不太清楚啦,难道是和进程中的线程调度神马的有关,我赶紧去上操作系统课。不过这里mHandler_2又把一个消息加到主线程的消息队列中了,这样不就实现了不同线程之间的通信了。这个方法可以用来通知UI线程刷新组件。
(六)从六到九条信息可以知道刚刚不管是Runnable对象还是Message,只要Handler是属于主线程的,那么处理这些事务都是在主线程当中进行的。
(七)第八条和第九条是一样的,那个是因为我犯得一个小错误啦,本来是想说明Message中what域的作用的,结果虽然用switch来区分不同的Message,但是完了把what输出来了。


我是菜鸟,我犯错我开心,希望大家能不吝指教,谢谢啦!
                转载请注明来自:http://zhenzxie.iteye.com/blog
  相关解决方案