Android之线程间通信

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()方法,消息都会被放到主线程的消息队列中去。


 <----------------------主线程给子线程发送消息-------------------------------->


 代码如下:
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 处理

 

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 
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>
 
运行结果:
 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值