android开发笔记之进程通信Messenger
来源:互联网 发布:js eval 不能用 编辑:程序博客网 时间:2024/05/17 04:58
写在前面的话
前面我写了一篇文章—android学习之remote service 的aidl详解,讲到跨进程多线程通信,我们使用aidl技术来实现。
但是平时我们大部分的应用可能只要要求跨进程通信,而不需要使用多线程,那么这时候,Messenger就是我们的一个非常好的选择。比起aidl来,Messenger实现更简单,并且不需要考虑线程安全的问题。
我参考了文章:
Android 基于Message的进程间通信 Messenger完全解析这里写链接内容
和官方文档:
android_sdk_docs_offline/guide/components/bound-services.html#Binding
大概弄明白了Messenger。
Messenger官方文档定义
Reference to a Handler, which others can use to send messages to it. This allows for the implementation of message-based communication across processes, by creating a Messenger pointing to a Handler in one process, and handing that Messenger to another process.
Messenger是基于消息的跨进程通信,Messenger要与Handler联合使用.
这个说的太抽象了,但是,我们可以看一下Messenger的几个关键方法:
二个构造方法:
Messenger(Handler target)
Create a new Messenger pointing to the given Handler.
Messenger(IBinder target)
Create a Messenger from a raw IBinder, which had previously been retrieved with getBinder().
发送消息的方法:
send(Message message)
Send a Message to this Messenger’s Handler.
Messenger实例
Server端:
MessengerService.java
import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.os.Messenger;import android.os.RemoteException;import android.util.Log;import android.widget.Toast;public class MessengerService extends Service { public static final String TAG = "MessengerService"; public static final int MSG_SEND_TO_SERVER = 1; public static final int MSG__REPLY_FROM_SERVER = 2; final Messenger mMessenger = new Messenger(new IncomingHandler()); class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SEND_TO_SERVER: Log.i(TAG, "MSG_SEND_TO_SERVER:"+"--msg.arg1:"+msg.arg1+"--msg.arg2:"+msg.arg2); try { Message messageReplyToClient = new Message(); messageReplyToClient.what = MSG__REPLY_FROM_SERVER; messageReplyToClient.arg1 = msg.arg2; messageReplyToClient.arg2 = msg.arg1; msg.replyTo.send(messageReplyToClient); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; default: super.handleMessage(msg); } } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); }}
大家会发现这个Server端的代码非常的简单,就是在onBind方法中返回一个mMessenger.getBinder()变量给client,并且定义一个Messenger mMessenger变量,mMessenger与IncomingHandler相关联,在handleMessage方法中处理client发送过来的信息。
我们在handleMessage方法可的主要操作是将client发送过来的Message的arg1和arg2值交换,再返回给client。
将消息返回给client端关键是要注意将要执行msg.replyTo的send方法:
msg.replyTo.send(messageReplyToClient);
在androidmanifest.xml中,我们定义service:
<service android:name=".MessengerService"> <intent-filter> <action android:name="com.android.ACTION.MessengerService" /> </intent-filter> </service>
Client端
MainActivity.java
import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.os.Messenger;import android.os.RemoteException;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;public class MainActivity extends Activity { public static final String TAG = "MainActivity"; public static final int MSG_SEND_TO_SERVER = 1; public static final int MSG__REPLY_FROM_SERVER = 2; private Messenger mMessenger; boolean mBound; private TextView textViewShowConnectState; private TextView textViewMessageSendToService; private TextView textViewMessageReceiverFromService; private Button button; private Messenger mMessengerReceive = new Messenger(new MyHandler()); class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG__REPLY_FROM_SERVER: Log.i(TAG, "MSG__REPLY_FROM_SERVER:"+"--msg.arg1="+msg.arg1+"--msg.arg2="+msg.arg2); textViewMessageReceiverFromService.setText("msg:server-->client:"+"--msg.arg1="+msg.arg1+"--msg.arg2="+msg.arg2); break; default: super.handleMessage(msg); } } } private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mMessenger = new Messenger(service); mBound = true; textViewShowConnectState.setText("service connect"); } public void onServiceDisconnected(ComponentName className) { mMessenger = null; mBound = false; textViewShowConnectState.setText("service disconnect"); } }; public void sendMessage(View v) { if (!mBound) return; // Create and send a message to the service, using a supported 'what' value int arg1 = (int) (Math.random() * 100);; int arg2 = (int) (Math.random() * 100);; Message msg = Message.obtain(null, MSG_SEND_TO_SERVER, arg1, arg2); msg.replyTo = mMessengerReceive; textViewMessageSendToService.setText("msg:client-->server:"+"--msg.arg1="+msg.arg1+"--msg.arg2="+msg.arg2); try { mMessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void init() { // TODO Auto-generated method stub textViewShowConnectState = (TextView)findViewById(R.id.textViewShowConnectState); textViewMessageSendToService = (TextView)findViewById(R.id.textViewMessageSendToService); textViewMessageReceiverFromService = (TextView)findViewById(R.id.textViewMessageReceiverFromService); button = (Button)findViewById(R.id.button); } @Override protected void onStart() { super.onStart(); bindService(new Intent("com.android.ACTION.MessengerService"), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); if (mBound) { unbindService(mConnection); mBound = false; } }}
我们Client给Server发送消息的是封装在sendMessage方法中的:
mMessenger.send(msg);
那么如何响应从server端回传的消息了,这中间的关键是把client发送到server的消息msg与回调处理的Messenger mMessengerReceive相关联:
msg.replyTo = mMessengerReceive;
布局文件:
activity_main.xml
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/textViewShowConnectState" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/textViewShowConnectState" android:onClick="sendMessage" android:text="click send message to Server" /> <TextView android:id="@+id/textViewMessageSendToService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/button"/> <TextView android:id="@+id/textViewMessageReceiverFromService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/textViewMessageSendToService"/></RelativeLayout>
效果图
从源码和效果图,我们可以看出,这个Demo是从Client发送一个消息到Server,Server把消息的msg.arg1和msg.arg2的值交换后再反馈给Client,Client将从Client发送到Server的消息和Server返回的消息都显示出来。
从这个Demo,我们也能非常明显的看出来,Messenger实现跨进程通信比aidl实现跨进程通信是更简单,更方便,条理也是更清晰。所以,如果实现跨进程非多线程的通信,我们推荐使用Messenger来实现。
- android开发笔记之进程通信Messenger
- android 进程通信之messenger
- Android开发——进程间通信之Messenger
- android进程间通信之Messenger
- Android进程间通信之Messenger
- Android进程间通信之使用Messenger
- Android进程间通信之Messenger浅析
- Android进程间通信之使用Messenger
- Android进程间通信(IPC)之Messenger
- 初识Android进程间通信之---Messenger
- Android进程间通信之Messenger
- android-----IPC进程间通信之Messenger
- Android 进程间通信之Messenger
- android—进程间通信之Messenger
- Android 进程间通信之使用Messenger
- Android 多进程通信之Messenger
- Android进程间通信之使用Messenger
- Android进程间通信之Messenger
- sysfs与ramfs、tmpfs、devtmpfs的一点区别
- CMD获取当前目录的绝对路径
- 初入CUDA: VS2010+cuda6.0工程的建立
- 浅谈算法和数据结构: 八 平衡查找树之2-3树
- HDOJ-1242-RESCURE(营救公主)【BFS+优先队列】
- android开发笔记之进程通信Messenger
- SYBASE --- all commands
- 浅谈算法和数据结构: 七 二叉查找树
- Ganymed SSH2 模拟putty远程交互式执行命令工具
- iptables 实现流量监控,重定向: 一
- scala实现设计模式之单例设计模式
- UITextField
- 湖南多校对抗赛(D-D)
- Python 之 安装模块的多种方法