关于handler的一些知识:
1、handler主要是用于主线程和子线程之间的通信,由于android在主线程之外的线程中不能操作UI,如果想要在子线程中改变UI,就需要使用handler。
2、handler可以想象成一个邮差,每天从Looper(消息循环,可以理解成邮政局)里取得含有消息的信件,然后交给线程处理。
3、每个线程仅有一个Looper,但可以有多个handler。
4、handler在哪个线程创建,就对应于哪个线程的Looper。用哪一个handler发送的消息,消息就会发送到该handler对应的Looper里。
5、创建handler前,必须先开启Looper,由于主线程在创建时默认已经开启了Looper,所以在主线程创建handler时中不需要开启Looper,但在子线程中必须要先Looper.prepare(),再创建handler,最后还要Looper.loop()。
下面通过一个小例子来练习一下handler在主线程和子线程中通信、改变UI的用法。
新建一个android工程,不需要改变main.xml文件,新建一个HandlertestActivity,其中代码如下:
package com.stormwy;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.widget.Toast;//练习在子线程中发送消息更新UI界面,以及主线程中发送消息给子线程。//想要达到的效果:主线程接收到子线程的消息后,显示一个alertdialog,//然后如果选择"YES",主线程就发送一个消息给子线程。//子线程接收到主线程的决定后,发回一个反馈消息给主线程。最后主线程UI界面提示子线程的反馈消息。public class HandlertestActivity extends Activity { /** Called when the activity is first created. */ Handler handler; Handler wife_handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 1) { wife_handler = (Handler)msg.obj; //接受传进来的子线程handler AlertDialog.Builder builder = new AlertDialog.Builder(HandlertestActivity.this);//新建一个Alertdialog的builder builder.setTitle("子线程说:"); builder.setMessage("你爱我吗?"); builder.setIcon(R.drawable.ic_launcher); builder.setPositiveButton("爱你", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Message backmsg = Message.obtain(); backmsg.what = 2; wife_handler.sendMessage(backmsg);//用子线程handler发送消息到子线程的looper } }); builder.setNegativeButton("不爱", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Message backmsg = Message.obtain(); backmsg.what = 4; wife_handler.sendMessage(backmsg);//用子线程handler发送消息到子线程的looper } }); builder.create(); builder.show(); } if(msg.what == 3 || msg.what == 5) { Toast.makeText(HandlertestActivity.this, "子线程说:"+msg.obj, 1000).show(); } } }; WifeThread thread = new WifeThread(handler); //创建一个WifeThread子线程对象 thread.start(); //开启线程 } public class WifeThread extends Thread{ Handler uihandler; Handler wifehandler; public WifeThread(Handler handler) { uihandler = handler; //利用构造函数接受主线程的handler,由于是内部类,其实直接用主线程的handler也可以。 } public void run() { super.run(); Looper.prepare(); //Android中,新建的线程默认是没有looper的,所以创建handler之前必须要先创建线程的Looper对象 wifehandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 2) { Message feedbackmsg = Message.obtain(); feedbackmsg.what = 3; feedbackmsg.obj = "我也爱你!"; uihandler.sendMessage(feedbackmsg);//使用主线程的handler发送消息到主线程的looper } if(msg.what == 4) { Message feedbackmsg = Message.obtain(); feedbackmsg.what = 5; feedbackmsg.obj = "好伤心啊"; uihandler.sendMessage(feedbackmsg);//使用主线程的handler发送消息到主线程的looper } } }; Message sendmsg = Message.obtain(); sendmsg.what = 1; sendmsg.obj = wifehandler; //利用Message.obj把子线程的handle传递给主线程。 uihandler.sendMessage(sendmsg); Looper.loop(); //Looper好像一定要放在最后才有效。 } } }
运行效果: