Android系统中实现了消息循环机制,不过这种消息机制是建立在线程之间的。
(1)Message : 线程间交流的信息。当负责处理数据的后台线程需要更新数据时,会发送Message给UI线程。
消息可以看成是一个信息的 封装集合,内部包含了进程之间需要交换的详细信息,被统一封装在android.os.Message中。
(2)MessageQueue :用来存放通过Handler发布的消息。
(3)Handler :是消息的处理器,负责Message的发送和Message内容的处理。
每个MessageQueue都会有一个对应的Handler,Handler通过sendMessage()和Post()来发送消息,这两种方式都会将消息 插在 队尾。 但这两种发送方式又略有不同,通过sendMessage()发送的是一个Message对象,会被handMessage()方法处理, 而通过Post()方式发送的是一个Runnable对象,则会自己执行。
(4) Lopper :Looper是消息队列MessageQueue的管理者,他负责维护管理MessageQueue,遍历MessageQueue中的消息。
通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得主线程的Looper对象。
注意,Android并不是为每个线程都会有一个消息队列,调用 Loop.myLooper() 往往返回的是NULL,只有在调用Looper.prepare()方法为当前线程建立一个消息队列,然后调用Looper.loop()方法对MessageQueue进行遍历。 但是Android会自动的为主线程(UI线程)建立MessageQueue,调用Looper.getMainLooper()得到主线程的Looper.
那么其他线程怎么把消息放入主线程的消息队列中去呢?答案是通过Handler对象,只要Handler对象以主线程的Looper创建, 那么 调用Handler的sendMessage()方法,消息都会被放到主线程的消息队列中去。
main.xml中的代码如下:
(1)Message : 线程间交流的信息。当负责处理数据的后台线程需要更新数据时,会发送Message给UI线程。
消息可以看成是一个信息的 封装集合,内部包含了进程之间需要交换的详细信息,被统一封装在android.os.Message中。
(2)MessageQueue :用来存放通过Handler发布的消息。
(3)Handler :是消息的处理器,负责Message的发送和Message内容的处理。
每个MessageQueue都会有一个对应的Handler,Handler通过sendMessage()和Post()来发送消息,这两种方式都会将消息 插在 队尾。 但这两种发送方式又略有不同,通过sendMessage()发送的是一个Message对象,会被handMessage()方法处理, 而通过Post()方式发送的是一个Runnable对象,则会自己执行。
(4) Lopper :Looper是消息队列MessageQueue的管理者,他负责维护管理MessageQueue,遍历MessageQueue中的消息。
通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得主线程的Looper对象。
注意,Android并不是为每个线程都会有一个消息队列,调用 Loop.myLooper() 往往返回的是NULL,只有在调用Looper.prepare()方法为当前线程建立一个消息队列,然后调用Looper.loop()方法对MessageQueue进行遍历。 但是Android会自动的为主线程(UI线程)建立MessageQueue,调用Looper.getMainLooper()得到主线程的Looper.
那么其他线程怎么把消息放入主线程的消息队列中去呢?答案是通过Handler对象,只要Handler对象以主线程的Looper创建, 那么 调用Handler的sendMessage()方法,消息都会被放到主线程的消息队列中去。
<----------------------主线程给子线程发送消息-------------------------------->
代码如下:
MainActivity中的代码如下:
package yxh.app.Message;
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;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
private final int MSG_HELLO = 0;
private Handler mHandler;
private Button btn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new CustomThread().start();// 新建并启动CustomThread实例
btn = (Button) findViewById(R.id.send_btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = "安徽大学";
Log.d("Test", "MainThread send message toCustomThread :" + str);
mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();// 发送消息到CustomThread实例
}
});
}
class CustomThread extends Thread {
@Override
public void run() {
Looper.prepare(); // 1、初始化Looper
mHandler = new Handler() { // 2、绑定handler到CustomThread实例的Looper对象
public void handleMessage(Message msg) { // 3、定义处理消息的方法
switch (msg.what) {
case MSG_HELLO:
Log.d("Test", "CustomThread receive message:"
+ (String) msg.obj);
}
}
};
Looper.loop(); // 4、启动消息循环
}
}
}
main.xml中的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:textColor="#ff0000"
android:layout_height="wrap_content"
android:text="主线程给自定义线程发送消息" />
<Button
android:id="@+id/send_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="send"
/>
</LinearLayout>
<----------------主线程给子线程发送消息,子线程收到信息并回复---------------->
本实例会创建两个消息队列,分别被 mainHandler, childHandler 处理
本实例会创建两个消息队列,分别被 mainHandler, childHandler 处理
package yxh.app.demo;
import android.app.Activity;
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.TextView;
public class MyThreadDemo extends Activity {
public static final int SETMAIN = 1;
public static final int SETCHILD = 2;
private Handler mainHandler, childHandler;
private TextView tv;
private Button but;
class ChildThread implements Runnable {
@Override
public void run() {
Looper.prepare(); // 初始化Looper,为子线程建立消息队列
childHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SETCHILD:
System.out.println("******主线程发给子线程的信息********: "+ msg.obj);//子线程得到主线程的数据信息,
//由此可以看出子线程收到了数据
Message MainMsg = mainHandler.obtainMessage(); // 创建Message
MainMsg.obj = "\n\n不要打我,我是子线程,名称为:"+ getLooper().getThread().getName(); //得到子线程名称:子线程1
MainMsg.what = SETMAIN;
mainHandler.sendMessage(MainMsg); // 发送到主线程队列的消息
break;
}
}
};
Looper.loop(); // 遍历该线程的消息队列
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.msg);
but = (Button) findViewById(R.id.but);
mainHandler = new Handler() { // 主线程的Handler对象
public void handleMessage(Message msg) {
switch (msg.what) { // 判断Message类型
case SETMAIN:
tv.setText("chlidThread把数据返回给主线程:"+ msg.obj.toString());
break;
}
}
};
//new Thread(runnable, threadName);
new Thread(new ChildThread(), "子线程1").start(); // 启动子线程
but.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (childHandler != null) {
Message childMsg = childHandler.obtainMessage(); // 创建一个子线程消息
childMsg.obj = mainHandler.getLooper().getThread().getName()+ " -->你是谁?快告诉我你的名字,不然我打你哦";
childMsg.what = SETCHILD;
childHandler.sendMessage(childMsg); // 发送子线程的队列的消息
}}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
childHandler.getLooper().quit(); // 结束队列
}
}
main.xml中的代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="
http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:textColor="#ff0000"
android:layout_height="wrap_content"
android:id="@+id/msg"
android:text="本例子是演示主线程给子线程发送消息,子线程收到消息并把处理结果返回给主线程。"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/but"
android:text="主子线程信息的交互"/>
</LinearLayout>
运行结果: