这是网上的一个使用例子:
- <span style="font-size: medium;">public class Activity2 extends Activity implements OnClickListener{
- Button button = null;
- TextView text = null;
- MyHandler mHandler = null;
- Thread thread ;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity1);
- button = (Button)findViewById(R.id.btn);
- button.setOnClickListener(this);
- text = (TextView)findViewById(R.id.content);
- }
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn:
- thread = new MyThread();
- thread.start();
- break;
- }
- }
- private class MyHandler extends Handler{
- public MyHandler(Looper looper){
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {//处理消息
- text.setText(msg.obj.toString());
- }
- }
- private class MyThread extends Thread{
- @Override
- public void run() {
- Looper curLooper = Looper.myLooper();
- Looper mainLooper = Looper.getMainLooper();
- String msg ;
- if(curLooper==null){
- mHandler = new MyHandler(mainLooper);
- msg = "curLooper is null";
- }else{
- mHandler = new MyHandler(curLooper);
- msg = "This is curLooper";
- }
- mHandler.removeMessages(0);
- Message m = mHandler.obtainMessage(1, 1, 1, msg);
- mHandler.sendMessage(m);
- }
- }
- }</span>
public class Activity2 extends Activity implements OnClickListener{
Button button = null;
TextView text = null;
MyHandler mHandler = null;
Thread thread ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity1);
button = (Button)findViewById(R.id.btn);
button.setOnClickListener(this);
text = (TextView)findViewById(R.id.content);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn:
thread = new MyThread();
thread.start();
break;
}
}
private class MyHandler extends Handler{
public MyHandler(Looper looper){
super(looper);
}
@Override
public void handleMessage(Message msg) {//处理消息
text.setText(msg.obj.toString());
}
}
private class MyThread extends Thread{
@Override
public void run() {
Looper curLooper = Looper.myLooper();
Looper mainLooper = Looper.getMainLooper();
String msg ;
if(curLooper==null){
mHandler = new MyHandler(mainLooper);
msg = "curLooper is null";
}else{
mHandler = new MyHandler(curLooper);
msg = "This is curLooper";
}
mHandler.removeMessages(0);
Message m = mHandler.obtainMessage(1, 1, 1, msg);
mHandler.sendMessage(m);
}
}
}
这个没有问题,基本上三个对象的使用也很清楚,myHandler虽然是由子线程new出来的,但主线程持有引用,在我们的项目中不能用,因为我们几个线程属于不同的类,我尝试用下面的方法解决:
在IoHandler中new一个android的handler,参数为主线程的Looper:
- <span style="font-size: medium;">new Handler(Looper.getMainLooper()).sendMessage(msg);</span>
new Handler(Looper.getMainLooper()).sendMessage(msg);
IoHandler所在的线程给主线程发送消息(looper是主线程的,消息也就放在主线程的消息队列里了)
但是在主线程的handleMessage方法中得不到消息,尝试失败。
那么怎么办呢,让IoHandler持有主线程的handler引用,具体做法有两种方式:
1. 参数传递,把主线程的handler通过参数传递的形式传到IoHandler中。
2. 静态变量,把主线程的handler申明为公共静态变量
- <span style="font-size: medium;">public static Handler mainHandler;</span>
public static Handler mainHandler;
这样在Iohandler中使用
- <span style="font-size: medium;">welcomeActivity.mainHandler.sendMessage(msg);</span>
welcomeActivity.mainHandler.sendMessage(msg);
这两种方式在主线程的 handleMessage的方法中都可以得到IoHandler发送的消息。
本人使用的是静态变量解决的,因为有好几个来实现通信,参数传递太麻烦。
那为什么我的第一种尝试是失败的呢,我是把消息放到主线程的消息队列了啊,这就要看android的一些实现机制了。
通过网络和android的api,本人的理解如下:
Looper是MessageQueue和Handler沟通的桥梁,Handler通过Looper把消息放入消息队列(MessageQueue),你想把消息发给谁,就把谁的looper作为参数传给Handler
- <span style="font-size: medium;">newHandler(Looper looper);</span>
newHandler(Looper looper);
Looper把消息放入消息队列,并广播消息,这个不太好理解,我举例如下:
主线程的Handler我们这样定义:Handler mainHandler = new Handler(); 如果Handler没有参数,默认为当前线程的Looper
子线程的Handler我们这样定义: Handler subHandler = newHandler(Looper.getMainLooper()); 参数为主线程的Looper
这样两个线程都会把消息放入主线程的消息队列里了。
现在mainHandler.sendMessage(), 消息进入主线程的消息队列,Looper广播消息,其实就是调用mainHandler的dispatchMessage方法,所有持有mianHandler引用的类都可以收到消息,注意啊,现在subHandler并不能接受到消息,因为Looper并没有调用subHandler的dispatchMessage方法,所以应该这样理解广播,A发送消息,那么A的Looper就调用A的dispatchMessage方法,别的B,C, D虽然也是A的Looper,但没有A的引用,所以B,C,D是接受不到消息的,如果B, C,D持有A的引用,但B,C,D不用A的Looper,那么也是接受不到消息的。这点在开发时要特别注意。