Message的机制:
这里有讲到机制:
http://blog.csdn.net/dadoneo/article/details/7667682 这里详细讲了,并且有代码示例,虽然比较长
http://blog.csdn.net/dadoneo/article/details/7667726
简单来说就是,每个线程都会有特定的一个消息队列,每个队列都会有特定的一个Looper,负责对消息队列的管理,注意这里都是有且只有一个,
用Looper可以构造Handler,Handler顾名思义就是handler the message,负责对消息的响应和处理
主线程不用初始化Looper,子线程需要初始化Looper,所以会看到在子线程构造Handler时会先 Looper.prepare(),之后会 Looper.loop()
Message用法
虽然new Message()也可以构造Message,Message.obtain() Handler.obtainMessage()可以从回收池中的Message中拿来用;
经常用到的是Handler.obtainMessage(int what, int arg1, int arg2, Object obj),what是一个标识,arg1和arg2也是自带的整型的标识,如果不用到就随便赋值,可以把要传的对象放在obj;
要发送到A线程,就用A线程的Handler去sendMessage
线程与UI更新
主线程才可以更新UI,子线程里更新会报错
这里有讲如何实现在子线程中更新UI
http://blog.csdn.net/veryitman/article/details/6384641
主线程与子线程之间的消息传递
package com.example.func;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity{
public static final int MAIN_THREAD = 1;
public static final int OTHER_THREAD = 2;
EventHandler mainHandler, handler1, handler2;
Button bt1, bt2, bt3, bt4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt1 = (Button)findViewById(R.id.main_to_main);
bt2 = (Button)findViewById(R.id.main_to_other);
bt3 = (Button)findViewById(R.id.other_to_main);
bt4 = (Button)findViewById(R.id.other_to_other);
MyListener mylistener = new MyListener();
bt1.setOnClickListener(mylistener);
bt2.setOnClickListener(mylistener);
bt3.setOnClickListener(mylistener);
bt4.setOnClickListener(mylistener);
// 默认构造函数是 EventHandler(Looper.mainLooper())
mainHandler = new EventHandler();
// 先开个子线程,在子线程中构造的 handler 是对应子线程消息队列的handler
// 注意之前要Looper.prepare(),之后要Looper.loop()
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare();
handler1 = new EventHandler(Looper.myLooper());
handler1.removeMessages(0);
Looper.loop();
while(true){
}
}
}).start();
}
private class MyListener implements OnClickListener{
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch(view.getId()){
case R.id.main_to_main:
// 主线程发给主线程
Message msg1 = mainHandler.obtainMessage(MAIN_THREAD, 1, 1, "a message from main thread");
mainHandler.sendMessage(msg1);
break;
case R.id.main_to_other:
// 主线程发给子线程
Message msg2 = handler1.obtainMessage(OTHER_THREAD, 1, 1, "a message from main thread");
handler1.sendMessage(msg2);
break;
case R.id.other_to_main:
// 子线程发给主线程
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Message msg3 = mainHandler.obtainMessage(MAIN_THREAD, 1, 1, "a message from other thread");
mainHandler.sendMessage(msg3);
}
}).start();
break;
case R.id.other_to_other:
// 子线程发给子线程
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Message msg4 = handler1.obtainMessage(OTHER_THREAD, 1, 1, "a message from other thread");
handler1.sendMessage(msg4);
}
}).start();
break;
default:
Toast.makeText(MainActivity.this, "default", Toast.LENGTH_SHORT).show();
break;
}
}
}
private class EventHandler extends Handler{
/**
* 除了default constructor外,还要定义能够根据looper构造handler的构造函数
* 这样在子线程中才能构造handler
* @param looper
*/
private EventHandler(Looper looper){
super(looper);
}
private EventHandler(){
super();
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
String str = null;
switch(msg.what){
case MAIN_THREAD:
// 这个handler是主线程的handler
str = msg.obj.toString() + " to main thread";
break;
case OTHER_THREAD:
// 这个handler是子线程的handler
str = msg.obj.toString() + " to other thread";
break;
default:
str = "default";
break;
}
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
super.handleMessage(msg);
}
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="@+id/main_to_main"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="main thread to main thread"/>
<Button
android:id="@+id/main_to_other"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="main thread to other thread"/>
<Button
android:id="@+id/other_to_main"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="other thread to main thread"/>
<Button
android:id="@+id/other_to_other"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="other thread to other thread"/>
</LinearLayout>