Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制。每个Hanlder都关联了一个线程,每个线程内部都维护了一个消息队列MessageQueue,这样Handler实际上也就关联了一个消息队列。可以通过Handler将Message和Runnable对象发送到该Handler所关联线程的MessageQueue(消息队列)中,然后该消息队列一直在循环拿出一个Message,对其进行处理,处理完之后拿出下一个Message,继续进行处理,周而复始。当创建一个Handler的时候,该Handler就绑定了当前创建Hanlder的线程。从这时起,该Hanlder就可以发送Message和Runnable对象到该Handler对应的消息队列中,当从MessageQueue取出某个Message时,会让Handler对其进行处理。
Handler可以用来在多线程间进行通信,在另一个线程中去更新UI线程中的UI控件只是Handler使用中的一种典型案例,除此之外,Handler可以做很多其他的事情。每个Handler都绑定了一个线程,假设存在两个线程ThreadA和ThreadB,并且HandlerA绑定了 ThreadA,在ThreadB中的代码执行到某处时,出于某些原因,我们需要让ThreadA执行某些代码,此时我们就可以使用Handler,我们可以在ThreadB中向HandlerA中加入某些信息以告知ThreadA中该做某些处理了。由此可以看出,Handler是Thread的代言人,是多线程之间通信的桥梁,通过Handler,我们可以在一个线程中控制另一个线程去做某事。
创建一个新的当前线程的handler
Handler handler = new Handler();
创建一个新的主线程的handler (UI Thread)
Handler handler = new Handler(Looper.getMainLooper());
Send a Runnable from another Thread to the main Thread:
new Thread(new Runnable() {
public void run() {
// this is executed on another Thread
// create a Handler associated with the main Thread
Handler handler = new Handler(Looper.getMainLooper());
// post a Runnable to the main Thread
handler.post(new Runnable() {
public void run() {
// this is executed on the main Thread
}
});
}
}).start();
实例:在主页面上加载一张网络图片,因为图片加载需要一定时间,所以用别的线程处理它,然后用handler来更新主线程里的UI。
import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.os.Handler;
import android.util.Log;
import android.widget.ImageView; import java.net.URL;
public class MainActivity extends ActionBarActivity { Handler h = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
new Thread(new Runnable() { public void run() {
// executed in the new thread
final Bitmap bmp = loadBitmap("<a target=_blank href="https://upload.wikimedia.org/wikipedia/en/1/17/Batman-BenAffleck.jpg">https://upload.wikimedia.org/wikipedia/en/1/17/Batman-BenAffleck.jpg</a>");
h.post(new Runnable() {
// executed in the UI thread via the handler
public void run() {
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(bmp); }
}); }
}).start(); }
public Bitmap loadBitmap(String url) {
Bitmap bmp = null;
try {
URL theUrl = new URL(url); bmp =
BitmapFactory.decodeStream(theUrl.openConnection().getInputStream()); }
catch(Exception e) { Log.d("g53mdp", e.toString());
}
return bmp; }