Messenger:使用消息的跨进程通信 (Message.replyTo()的使用)

原文链接:http://xwangly.iteye.com/blog/1109424

Messenger:信使

官方文档解释:它引用了一个Handler对象,以便others能够向它发送消息(使用mMessenger.send(Message msg)方法)。该类允许跨进程间基于Message的通信(即两个进程间可以通过Message进行通信),在服务端使用Handler创建一个Messenger,客户端持有这个Messenger就可以与服务端通信了。

以前我们使用Handler+Message的方式进行通信,都是在同一个进程中,从线程持有一个主线程的Handler对象,并向主线程发送消息。

而Android既然可以使用bindler机制进行跨进行通信,所以我们当然可以将Handler与bindler结合起来进行跨进程发送消息。

查看API就可以发现,Messenger就是这种方式的实现。

一般使用方法如下:

1。远程通过

mMessenger = new Messenger(mHandler)

 创建一个信使对象

2。客户端使用bindlerService请求连接远程

3。远程onBind方法返回一个bindler

return mMessenger.getBinder();
 4.客户端使用远程返回的bindler得到一个信使(即得到远程信使)
          public void onServiceConnected(ComponentName name, IBinder service) {rMessenger = new Messenger(service);......}

 这里虽然是new了一个Messenger,但我们查看它的实现
    /*** Create a Messenger from a raw IBinder, which had previously been* retrieved with {@link #getBinder}.* * @param target The IBinder this Messenger should communicate with.*/public Messenger(IBinder target) {mTarget = IMessenger.Stub.asInterface(target);}

 发现它的mTarget是通过Aidl得到的,实际上就是远程创建的那个。

5。客户端可以使用这个远程信使对象向远程发送消息:rMessenger.send(msg);

这样远程服务端的Handler对象就能收到消息了,然后可以在其handlerMessage(Message msg)方法中进行处理。(该Handler对象就是第一步服务端创建Messenger时使用的参数mHandler).

经过这5个步骤貌似只有客户端向服务端发送消息,这样的消息传递是单向的,那么如何实现双向传递呢?

首先需要在第5步稍加修改,在send(msg)前通过msg.replyTo = mMessenger将自己的信使设置到消息中,这样服务端接收到消息时同时也得到了客户端的信使对象了,然后服务端可以通过

//得到客户端的信使对象,并向它发送消息
cMessenger = msg.replyTo;
cMessenger.send(message);

即完成了从服务端向客户端发送消息的功能,这样客服端可以在自己的Handler对象的handlerMessage方法中接收服务端发送来的message进行处理。

双向通信宣告完成。

下面改写ApiDemos工程实现Messenger通信

MessengerService.java

package com.xwangly.apidemo.app;import java.util.Random;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;public class MessengerService extends Service {private String TAG = "MessengerService";@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i(TAG, "onDestroy");cMessenger = null;super.onDestroy();}@Overridepublic boolean onUnbind(Intent intent) {// TODO Auto-generated method stubLog.i(TAG, "onUnbind");return super.onUnbind(intent);}static final int MSG_REGISTER_CLIENT = 1;static final int MSG_UNREGISTER_CLIENT = 2;static final int MSG_SET_VALUE = 3;private Random random = new Random();private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubLog.i(TAG, "handleMessage");switch (msg.what) {case MSG_SET_VALUE:try {Message message = Message.obtain(null,MessengerService.MSG_SET_VALUE);message.arg1 = random.nextInt(100);//得到客户端的信使对象,并向它发送消息cMessenger = msg.replyTo;cMessenger.send(message);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}break;default:super.handleMessage(msg);}}};/*** 自己的信使对象*/private Messenger mMessenger = new Messenger(mHandler);/*** 客户的信使*/private Messenger cMessenger;@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i(TAG, "onBind");//返回自己信使的bindler,以供客户端通过这个bindler得到服务端的信使对象(通过new Messenger(bindler))return mMessenger.getBinder();}@Overridepublic void onRebind(Intent intent) {// TODO Auto-generated method stubLog.i(TAG, "onRebind");}}

MessengerServiceActivities.java

package com.xwangly.apidemo.app;import com.xwangly.apidemo.R;import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
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.TextView;public class MessengerServiceActivities {public static class Binding extends Activity implementsView.OnClickListener {private String TAG = "Binding";TextView mCallbackText;private boolean isBound;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.messenger_service_binding);findViewById(R.id.bind).setOnClickListener(this);findViewById(R.id.unbind).setOnClickListener(this);mCallbackText = (TextView) findViewById(R.id.callback);mCallbackText.setText("Not attached.");}private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {Log.i(TAG, "handleMessage");switch (msg.what) {case MessengerService.MSG_SET_VALUE:mCallbackText.setText("Received from service: " + msg.arg1);break;default:super.handleMessage(msg);}}};/*** 自己的信使*/private Messenger mMessenger;/*** 远程服务的信使*/private Messenger rMessenger;private ServiceConnection connection = new ServiceConnection() {public void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubLog.i(TAG, "onServiceConnected");rMessenger = new Messenger(service);mMessenger = new Messenger(mHandler);sendMessage();}public void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubrMessenger = null;}};public void onClick(View v) {// TODO Auto-generated method stubIntent intent = new Intent("com.xwangly.apidemo.app.messenger_service");switch (v.getId()) {case R.id.bind:if (!isBound) {isBound = bindService(intent, connection, BIND_AUTO_CREATE);//isBound = true;}else {sendMessage();}break;case R.id.unbind:if (isBound) {unbindService(connection);isBound = false;}break;default:break;}}/*** 使用服务端的信使向它发送一个消息。*/private void sendMessage() {// TODO Auto-generated method stubMessage message = Message.obtain(null, MessengerService.MSG_SET_VALUE);message.replyTo = mMessenger;try {rMessenger.send(message);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

配置文件 AndroidManifest.xml相关配置如下:

     <service android:name=".app.MessengerService" ><intent-filter><action android:name="com.xwangly.apidemo.app.messenger_service" /></intent-filter></service><activity android:name=".app.MessengerServiceActivities$Binding"android:label="@string/activity_messenger_service_binding"android:launchMode="singleTop"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

Messenger:使用消息的跨进程通信 (Message.replyTo()的使用)相关推荐

  1. [转]Messenger:使用消息的跨进程通信

    本文转自:http://xwangly.iteye.com/blog/1109424 Messenger:信使 官方文档解释:它引用了一个Handler对象,以便others能够向它发送消息(使用mM ...

  2. Android 使用Messenger和Aidl实现跨进程通信

    Android Messenger和Aidl的使用 1.怎么使用多进程 为安卓的四大组件设置process属性值 例如:android:process=":test"或者 andr ...

  3. Android跨进程通信一 Messenger

    实现客户端与服务端之间的交互 说明:         Messenger是信使的意思,从它的名字就可以了解到它充当着信差的角色.Android通过它实现跨进程通信,主要有客户端信使与服务端信使两种角色 ...

  4. 利用Messenger跨进程通信

    在进行跨进程通信的时候,可能很多开发者一开始想到的就是AIDL.AIDL,中文名称是android接口描述语言,是android系统中用于进行跨进程通信必须了解的.至于如何生成远程对象进行AIDL通信 ...

  5. Android IPC 进程进程间通信或跨进程通信

    Android IPC 机制 老话长谈,趁现在有时间对IPC做一个具体的总结. IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间 ...

  6. Android跨进程通信

    一 多进程之间的通信 由于不同进程所拥有的地址是两块不同的地址空间,所以不能直接通过共享内存共享数据了. Linux常用跨进程通信方式:管道,信号量,共享内存,socket Android常用跨进程通 ...

  7. 使用AIDL+动态代理+运行时注解+反射 反手撸一套Android跨进程通信框架

    IPC 前言 跨进程通信方式 跨进程通信框架 涉及到的技术 使用Request-Response思想 IPCRequest IPCResponse RemoteService 服务端 客户端 附带 项 ...

  8. Android的跨进程通信

    Android系统的跨进程简介 为什么不能直接跨进程通信? 为了安全考虑,应用之间的内存是无法互相访问的,各自的数据都存在于自身的内存区域内. 如何跨进程通信? 要想跨进程通信,就要找到一个大家都能访 ...

  9. 【朝花夕拾】Android跨进程通信总结篇

    前言 原文:https://www.cnblogs.com/andy-songwei/p/10256379.html 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一. ...

  10. 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10256379.html],谢谢! 只要是面试高级工程师岗位,Android跨进程通信就是最受面 ...

最新文章

  1. 神经科学如何影响人工智能?看DeepMind在NeurIPS2020最新《神经科学人工智能》报告,126页ppt...
  2. 华硕服务器如何安装系统安装win7系统,华硕电脑怎么重新安装win7系统
  3. CentOS6.7安装SBT
  4. staem被盗_如何检查照片是否被盗
  5. java ee的小程序_Java EE调度程序
  6. three20 TTTableViewController + TTActionSheetController
  7. VC2008 Windows Media Player控件的使用技巧
  8. 图像算法八:【图像分割】边缘检测(Roberts,Sobel,canny)、霍夫变换(hough)、阈值分割、区域分割
  9. 同步异步、阻塞非阻塞
  10. python200行代码_python代码统计200行
  11. C# Parse和Convert的区别分析
  12. 怎么在Linux中telnet服务器,Linux系统下Telnet服务器配置
  13. CloudFlare Full SSL Strict 报错提示 Error 525 SSL handshake failed
  14. 渗透之——Nmap+Zenmap+Amap+Zmap
  15. rpc调用 java_RPC调用的简单实现
  16. 去掉flash player自带的fff新推荐广告插件
  17. 引爆Spark大数据引擎的七大工具
  18. 欧若科技通过 OpenKG 开放 Nebula Graph 图数据库
  19. C4D渲染保存多通道psd格式,图层都是线性减淡模式,oc多通道图层都是线性简单模式
  20. Fallback class must implement the interface annotated by @FeignClient

热门文章

  1. 找不到Break键怎么Quit / 退出服务CTRL-BREAK怎么输入啊?/ 笔记本键盘上没有break键
  2. orcad的交流分析
  3. matlab三维网格绘图函数mesh、meshc、mesh、zmeshgrid、surf【matlab图行绘制五】
  4. Unity 2D人物移动实现
  5. Python3中使用flask_sqlalchemy的问题
  6. 液晶显示技术 TCON介绍
  7. 装配图中齿轮的画法_机械制图之装配图
  8. Vue学习笔记:获取文件唯一标识 md5值
  9. python输出斐波那契数列_如何用Python输出一个斐波那契Fibonacci数列
  10. 静态分析Android程序