關於handler的一些知識:java
一、handler主要是用於主線程和子線程之間的通訊,因爲android在主線程以外的線程中不能操做UI,若是想要在子線程中改變UI,就須要使用handler。android
二、handler能夠想象成一個郵差,天天從Looper(消息循環,能夠理解成郵政局)裏取得含有消息的信件,而後交給線程處理。web
三、每一個線程僅有一個Looper,但能夠有多個handler。app
四、handler在哪一個線程建立,就對應於哪一個線程的Looper。用哪個handler發送的消息,消息就會發送到該handler對應的Looper裏。ide
五、建立handler前,必須先開啓Looper,因爲主線程在建立時默認已經開啓了Looper,因此在主線程建立handler時中不須要開啓Looper,但在子線程中必需要先Looper.prepare(),再建立handler,最後還要Looper.loop()。函數
下面經過一個小例子來練習一下handler在主線程和子線程中通訊、改變UI的用法。oop
新建一個android工程,不須要改變main.xml文件,新建一個HandlertestActivity,其中代碼以下:ui
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好像必定要放在最後纔有效。 } } }
運行效果:this