andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。

在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个事android的新 概念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handle,我们有消息循环,就要往消息循环里 面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,消息的的处理,把这些都封装在Handle里面,注意Handle只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。 但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。

但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。

一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列。如下面的代码:

Java代码
class ChildThread extends Thread {

public void run() {

/*
* 创建 handler前先初始化Looper.
*/
Looper.prepare();

/*
* 在子线程创建handler,所以会绑定到子线程的消息队列中
*
*/
mChildHandler = new Handler() {

public void handleMessage(Message msg) {

/*
* Do some expensive operations there.
*/
}
};

/*
* 启动该线程的消息队列
*/
Looper.loop();

}
}




当Handler收到消息后,就会运行handleMessage(…)的回调函数,可以在里面做一些耗时的操作。




最后完成了操作要结束子线程时,记得调用quit()来结束消息循环队列。

mChildHandler.getLooper().quit();



下面是一个线程间通信的小例子:

public class omg extends Activity
{
private static final String TAG = "MainThread";
private Handler mMainHandler = null;
private TextView info = null;
private Button msgBtn = null;
private Button btn1 = null;
private int nClick = 0;
ChildThread child1 = null;
ChildThread child2 = null;

class ChildThread extends Thread {
private Handler childHander = null;
private int nClickTimes = 0;
private static final String CHILD_TAG = "ChildThread";

public void run() {
this.setName("ChildThread");

// 初始化消息循环队列,需要在Handler创建之前
Looper.prepare();

childHander = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(CHILD_TAG,
"Got an incoming message from the main thread - "
+ (String) msg.obj);

try {

// 在子线程中可以做一些耗时的工作
String sMsg = "";
sleep(1000);

Message toMain = new Message();

// mMainHandler.obtainMessage();
sMsg = String.valueOf(++nClickTimes);
toMain.obj = sMsg + "This is "
+ this.getLooper().getThread().getName()
+ ". 你发送了消息: \"" + (String) msg.obj + "\"?"
+ "这是弟" + sMsg + "次 ";

mMainHandler.sendMessage(toMain);
Message toChild = new Message();
toChild.obj = "over";
// mChildHandler.sendMessage(toChild);

Log.i(CHILD_TAG, "Send a message to the main thread - "
+ (String) toMain.obj);

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

};

// 启动子线程消息循环队列
Looper.loop();

}
}

// //////////////////////////////////////////////////////////////////////////

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

info = (TextView) findViewById(R.id.info);
msgBtn = (Button) findViewById(R.id.msgBtn);
btn1 = (Button) findViewById(R.id.button1);

mMainHandler = new Handler() {

@Override
public void handleMessage(Message msg) {
Log.i(TAG, "Got an incoming message from the child thread - "
+ (String) msg.obj);

// 接收子线程的消息
info.setText((String) msg.obj + String.valueOf(nClick));
}

};

child1 = new ChildThread();
child1.start();

child2 = new ChildThread();
child2.start();

msgBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

if (child1.childHander != null) {

// 发送消息给子线程
Message childMsg = child1.childHander.obtainMessage();
Message msg = new Message();
msg.obj = mMainHandler.getLooper().getThread().getName()
+ " says Hello and msbBtn sending";

child1.childHander.sendMessage(msg);
Log.i(TAG, "Send a message to the child thread - "
+ (String) msg.obj);
}
}
});

btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (child2.childHander != null) {

// 发送消息给子线程
Message childMsg = child2.childHander.obtainMessage();
Message msg = new Message();
msg.obj = mMainHandler.getLooper().getThread().getName()
+ " says Hello and btn1 sending";
child2.childHander.sendMessage(msg);
Log.i(TAG, "Send a message to the child thread - "
+ (String) msg.obj);
}

}

});

}

public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Stop looping the child thread's message queue");

if (child1.childHander != null) {
child1.childHander.getLooper().quit();
}
if (child2.childHander != null) {
child2.childHander.getLooper().quit();
}

}
}

更多相关文章

  1. Android任务、进程、线程详解
  2. Android中高效的显示图片之二——在非UI线程中处理图片
  3. Android的消息处理机制——Looper,Handler和Message浅析
  4. Android和ROS的通信 消息的传递
  5. 利用NotificationListenerService获取微信通知消息的头像和内容
  6. Android Handler消息队列的实现原理

随机推荐

  1. Android自带的TabLayout实现滑动翻页效果
  2. 【android】解决在图库中缩略图与实际图
  3. Android架构组件WorkManager详解
  4. android 实现屏幕截图
  5. 04.Android的数据存储操作
  6. Android修改主题,去掉ActionBar、TitleBar
  7. android 悬浮窗教程
  8. Android让帧动画在结束时消失
  9. Hack4-自定义PreferenceActivity界面
  10. Android图片缩放总结及比较