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放入Message的callback中,然后傳入消息隊列。
Loop取出帶有Runnable的Message后,判斷是否有callback屬性,有則執行handleCallback(Message msg),然后在此方法中執行run方法,沒有new一個Thread,一般在這個run()方法中寫入需要在UI線程上的操作。
用這樣的機制可以彌補沒有語句塊的缺憾。(oc語言)
另外,有兩遍關于Handler很好的博文:
Android--多線程之Handler
Android的線程使用來更新UI----Thread、Handler、Looper、TimerTask等
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。