Android Handler Looper Message MessageQueue Threadandroid
Handler負責發送Message和處理Message.app
Handler處理Message必須對應一個Looper,Looper負責從MessageQueue中抽取Message.ide
若是Handler定義在main thread( ui thread)中,那麼默認狀況下系統會給其關聯一個Looper。因此ui thread中定義的Handler能夠更新UI.oop
若是Handler定義在非主線程中,必需要有一個Looper與之關聯,才能處理Message。通常post
class MyThread extends Thread() {ui
private Handler mHandler;this
public void run() {線程
Looper.prepare();orm
mHandler = new Handler() {get
public void handleMessage(Message msg) {
// process incoming messages here
}
}
Looper.loop();
}
}
使用Handler的時候要注意,Handler在哪一個線程中定義,不正確的線程中直接更新UI將引起異常。
幾種從其餘線程訪問UI線程:
- Activity.runOnUiThread(Runnable);
- View.post(Runnable)
- View.postDelayed(Runnable, long)
- Handler實現線程間的通訊
- AsyncTask
package com.leamiko.activity;
import com.leamiko.orm.R;
import android.app.Activity;
import android.os.AsyncTask;
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 TextView txView;
private Button button;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i("RootyInfo", "oncreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txView = (TextView) findViewById(R.id.textView1);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 建立一個用於展現前三種後臺線程和UI線程交互的線程
new TestThread(MainActivity.this).start();
// 建立一個用於展現AsyncTask實現交互的TestAsyncTask
new TestAsyncTask().execute("Test", " AsyncTask");
}
});
}
class TestAsyncTask extends AsyncTask<String, Integer, String> {
// TestAsyncTask被後臺線程執行後,被UI線程被調用,通常用於初始化界面控件,如進度條
@Override
protected void onPreExecute() {
super.onPreExecute();
}
// doInBackground執行完後由UI線程調用,用於更新界面操做
@Override
protected void onPostExecute(String result) {
txView.setText(result);
super.onPostExecute(result);
}
// 在PreExcute執行後被啓動AysncTask的後臺線程調用,將結果返回給UI線程
@Override
protected String doInBackground(String... params) {
StringBuffer sb = new StringBuffer();
for (String string : params) {
sb.append(string);
}
return sb.toString();
}
}
// 用於線程間通訊的Handler
class TestHandler extends Handler {
public TestHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
txView.setText((String) msg.getData().get("tag"));
super.handleMessage(msg);
}
}
// 後臺線程類
class TestThread extends Thread {
Activity activity;
public TestThread(Activity activity) {
this.activity = activity;
}
@Override
public void run() {
// 下面代碼用來演示Activity.runOnUIThread(Runnable)方法的實現
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txView.setText("Test runOnUIThread");
}
});
// 下面代碼用來演示Activity.runOnUIThread(Runnable)方法的實現
txView.post(new Runnable() {
@Override
public void run() {
txView.setText("Test View.post(Runnable)");
}
});
// 下面代碼用來演示Activity.runOnUIThread(Runnable)方法的實現
txView.postDelayed(new Runnable() {
@Override
public void run() {
txView.setText("Test View.postDelay(Runnable,long)");
}
}, 1000);
// 下面代碼用來演示Handler方法的實現
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putString("tag", "Test Handler");
msg.setData(bundle);
new TestHandler(Looper.getMainLooper()).sendMessage(msg);
}
}
}