Handler会关联一个单独的线程和消息队列。Handler默认关联主线程,虽然要提供Runnable参数,但默认是直接调用Runnable中的run()方法。也就是默认下会在主线程执行,如果在这里面的操作会有阻塞,界面也会卡住。如果要在其他线程执行,可以使用HandlerThread。
HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息。
package com.goma.handlertwo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
public class HandlerActivity extends Activity {
private Handler handler = null;
private ProgressBar progressBar = null;
private int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
progressBar = (ProgressBar)findViewById(R.id.pb_id);
Button start = (Button)findViewById(R.id.start);
Button stop = (Button)findViewById(R.id.stop);
System.out.println("HandlerActivity:::::"+Thread.currentThread().getId());
handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("Handler.CallBack::::" + Thread.currentThread().getId());
progressBar.setProgress(msg.arg1);
progressBar.setSecondaryProgress(msg.arg1 + 5 );
return false;
}
});
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.post(run);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.removeCallbacks(run);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.handler, menu);
return true;
}
Runnable run = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("##########"+Thread.currentThread().getId());
handler.postDelayed(run, 2000);
Message msg = handler.obtainMessage();
msg.arg1 = i * 10 ;
i++;
handler.sendMessage(msg);
}
};
}
上面代码System.out输出线程ID相同
package com.goma.handlerthreaddemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class HandlerThreadActivity extends Activity {
Handler handler = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_thread);
System.out.println("------------------>" + Thread.currentThread().getId());
HandlerThread ht = new HandlerThread("MyThread");
ht.start();
handler = new Handler(ht.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
int tmp = msg.arg1;
System.out.println(Thread.currentThread().getId() + "::::::::::::" + tmp);
return false;
}
});
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.post(run);
}
});
Button btn2 = (Button) findViewById(R.id.btn2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.removeCallbacks(run);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.handler_thread, menu);
return true;
}
Runnable run = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
handler.postDelayed(run, 5000);
Message msg = handler.obtainMessage();
msg.arg1 = 1123;
handler.sendMessage(msg);
System.out.println("###################" + Thread.currentThread().getId());
}
};
}
从上面代码看线程ID是不同的,有两个一个主线程、一个HandlerThread线程
==========================================================
另:我在学习HandlerThread、Thread时,我就向为什么不:
Thread t = new Thread(Runnable);
t.start();
后来弄明白了,其实Runnable是在Handler执行的,但是Handler默认绑定主线程,
所以采用这种方法,在Thread.start()确是新生成一个线程,但是在Handler.post(Runnable)后,
runnable方法又会被绑定到主线程中执行。
==========================================================================
另可参考:http://blog.sina.com.cn/s/blog_5da93c8f0101kio1.html