Android主线程与子线程之间的通信

来源:互联网 发布:xgpush java开发 编辑:程序博客网 时间:2024/05/01 04:37

在android中主线程与子线的通信往往会使用到Handler,Looper,MessageQueen,Message。首先简单的来介绍下他们在通信之间中的作用,以及相关使用方法。


Handler:相当于消息队列中具体处理消息的工人。可以有多个
Looper:相当于消息队列中的管家。只有1个。
MessageQueen:存放消息的队列。
Message:传递信息的消息体

它就像一个消息队列(MessageQueue)的管家(Looper),一个消息队列只有一个管家,并且管理者整个消息队列,而一个消息队列内可以容纳多个消息(Message),而工人(Handler)也可以有多个,管家派遣他们向消息队列中存储或取出消息后执行任务;所以它们的个数如下: 

管家(Looper): 1 个; 

消息队列(MessageQueue):1 个; 
消息(Message):可以多个; 
工人(Handler):可以多个;


 1. 主线程往子线程中发消息:
由于子线程中并没有消息队列,所以首先需要初始化消息队列(Looper.prepare()),以及启动消息循环(Looper.loop())。只有这样才能在子线程中使用Handler来捕获从主线程传过来的消息。详细的请看下面代码,实现了主线程发送一条消息到子线程,子线程接收到消息后将值用Toast显示出来。

package com.vic.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;import android.widget.Toast;public class TextActivity extends Activity{/** * 主线程发送消息到子线程 *///主线程发送消息到子线程按钮private Button mButton = null;//子线程更新textView的值private TextView mText = null;private int num = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);super.setContentView(R.layout.text_layout);mButton = (Button) findViewById(R.id.send_msg_sub_thread);mText = (TextView) findViewById(R.id.update_text);final SubThread subThread = new SubThread();subThread.start();mButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Message msg = Message.obtain();msg.arg1 = num ;subThread.subHandler.sendMessage(msg);num ++;}});}private class SubThread extends Thread{Handler subHandler = null;@Overridepublic void run() {//初始化looperLooper.prepare();subHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {Toast.makeText(TextActivity.this, "子线程收到消息:" + msg.arg1, Toast.LENGTH_SHORT).show();}};//启动消息循环Looper.loop();}}}


代码执行结果如下图所示:

2. 子线程往主线程中发消息:

子线程往主线程中发送消息就比较简单了,因为在主线程中默认已经实现了消息队列。即已经实现了Looper.prepare()以及Looper.loop(),所以我们直接从子线程发送消息后,主线程用handler接收就可以了。下面的代码实现了在主线程中启动了一个子线程,子线程向主线程发送消息后,主线程更新textview的操作。

package com.vic.thread;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.widget.TextView;import com.vic.demo.R;public class Sub2MainThread extends Activity{private TextView mText = null;Handler mainHandler = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.sub2main);mText = (TextView) findViewById(R.id.main_text);//子线程启动new SubThread().start();//接收子线程发送过来消息,并更新UImainHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);mText.setText("从子线程接收到的消息为:" + msg.arg1);}};}class SubThread extends Thread{@Overridepublic void run() {super.run();Message msg = Message.obtain();msg.arg1 = 1;mainHandler.sendMessage(msg);}}}
代码执行结果如下

总结:android主线程与子线程之间的通信往往是通过handler,Looper以及message来实现的。关键在于如果线程中没有实现消息队列的机制,需要通过调用Looper.prepare()以及Looper.loop()来建立好消息传送的通道。而主线程默认已经实现了消息 队列的相关机制,就不需要再进行消息初始化的操作了,直接调用handler的handleMessage方法来处理从子线程传递过来的消息。


1 1
原创粉丝点击