Handler

  Handler,它直接继承自Object,一个Handler允许发送和处理Message或者Runnable对象,并且会关联到主线程的MessageQueue中。每个Handler具有一个单独的线程,并且关联到一个消息队列的线程,就是说一个Handler有一个固有的消息队列。当实例化一个Handler的时候,它就承载在一个线程和消息队列的线程,这个Handler可以把Message或Runnable压入到消息队列,并且从消息队列中取出Message或Runnable,进而操作它们。


一下是一个简单的例子。两个按钮只是测试用的。点击按钮后,将改变TextView的文字。

package com.jam.testhandler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

	private Button button1;
	private Button button2;
	private TextView textView;
	private MyHandler handler;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		handler = new MyHandler();
		button1 = (Button) findViewById(R.id.button1);
		button2 = (Button) findViewById(R.id.button2);
		textView = (TextView) findViewById(R.id.textView);
		button1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Thread t = new MyWorkThread();
				t.start();
			}
		});
		button2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				TestThread tt = new TestThread();
				Thread thread = new Thread(tt);
				thread.start();
			}
		});
	}

	//集成Thread的方法
	private class MyWorkThread extends Thread {

		@Override
		public void run() {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			String s = "String from work thread";
			
			//这里我没弄清楚obtainMessage和new Message的区别。
//			Message msg = handler.obtainMessage();
			Message msg = new Message();
			
			msg.obj = s;
			handler.sendMessage(msg);
		}
		
	}
	
	//实现Runnable
	//注意Runnable代表线程体而不是一个线程
	private class TestThread implements Runnable {

		@Override
		public void run() {
			Runnable r = new Runnable() {
				
				@Override
				public void run() {
					System.out.println("Thread的名字-->" + Thread.currentThread().getName());
				}
			};
			
			handler.post(r);
		}
		
	}
	
}

  Handler 发送的 message 到队列中后,Looper 拿到后会返回到发送消息的Handler中处理。

  Handler拿到后,在这个例子中,由于Handler是在主线程当中,所以这个机制可以另其他线程处理的东西拿到Handler中,再进行UI的修改。


以下是另一种用法,在新的线程中使用Handler

package com.example.testhandler2;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

	private Button button;
	private TextView textView;
	private Handler handler;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		button = (Button) findViewById(R.id.button);
		textView = (TextView) findViewById(R.id.textView);
		
		button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Message msg = new Message();
				msg.what = 50;
				handler.sendMessage(msg);
			}
		});
		
		WorkerThread workerThread = new WorkerThread();
		workerThread.start();
	}

	private class WorkerThread extends Thread {

		@Override
		public void run() {
			Looper.prepare();
			handler = new Handler() {

				@Override
				public void handleMessage(Message msg) {
					Log.d("msg", "" + msg.what);
				}
				
			};
			Looper.loop();
		}

	} 
	
}

在点击按钮后,使用handler发送数据,在另一个线程中把数据取出来。


在子线程创建使用Handler要注意固定用法:

先准备Loop

Looper.prepare()

复写Handler的方法handleMessage

Looper.loop


注意:

Thread代表线程

Runnable代表线程体不是一个线程线程体传入线程才能用

Handler在哪个线程生成Looper就在哪个线程

 

  Handler.post()方法 将一个Runnable放入Messagecallback然后传入消息队列。

  Loop取出带有RunnableMessage判断是否有callback属性有则执行handleCallback(Message msg),然后在此方法中执行run方法没有new一个Thread,一般在这个run()方法中写入需要在UI线程上的操作。


用这样的机制可以弥补没有语句块的缺憾。(oc语言)


另外,有两遍关于Handler很好的博文:

Android--多线程之Handler

Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等