標籤:handler
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;@Overrideprotected 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() {@Overridepublic void onClick(View v) {Thread t = new MyWorkThread();t.start();}});button2.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {TestThread tt = new TestThread();Thread thread = new Thread(tt);thread.start();}});}//整合Thread的方法private class MyWorkThread extends Thread {@Overridepublic 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 {@Overridepublic void run() {Runnable r = new Runnable() {@Overridepublic 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;@Overrideprotected 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() {@Overridepublic 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 {@Overridepublic void run() {Looper.prepare();handler = new Handler() {@Overridepublic 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放入Message的callback中,然後傳入訊息佇列。
Loop取出帶有Runnable的Message後,判斷是否有callback屬性,有則執行handleCallback(Message msg),然後在此方法中執行run方法,沒有new一個Thread,一般在這個run()方法中寫入需要在UI線程上的操作。
用這樣的機制可以彌補沒有語句塊的缺憾。(oc語言)
另外,有兩遍關於Handler很好的博文:
Android--多線程之Handler
Android的線程使用來更新UI----Thread、Handler、Looper、TimerTask等
Android學習筆記:Handler初步