Android IPC机制Messenger实例详解

Android IPC机制Messenger实例详解

前言:

Messenger可以翻译成信使,通过它可以在不同进程间传递Message对象有了它就可以轻松实现进程间的数据传递了。

Messenger使用的方法相对AIDL比较简单,它对AIDL做了一层封装是的我们不需要像采用AIDL那样去实现进程通信那么麻烦,可以看看他的源码有AIDL的迹象。

public final class Messenger implements Parcelable {
  private final IMessenger mTarget;

  public Messenger(Handler target) {
    mTarget = target.getIMessenger();
  }

  public void send(Message message) throws RemoteException {
    mTarget.send(message);
  }

  public IBinder getBinder() {
    return mTarget.asBinder();
  }

  public boolean equals(Object otherObj) {
    if (otherObj == null) {
      return false;
    }
    try {
      return mTarget.asBinder().equals(((Messenger)otherObj)
          .mTarget.asBinder());
    } catch (ClassCastException e) {
    }
    return false;
  }

  public int hashCode() {
    return mTarget.asBinder().hashCode();
  }

  public int describeContents() {
    return 0;
  }

  public void writeToParcel(Parcel out, int flags) {
    out.writeStrongBinder(mTarget.asBinder());
  }

  public static final Parcelable.Creator<Messenger> CREATOR
      = new Parcelable.Creator<Messenger>() {
    public Messenger createFromParcel(Parcel in) {
      IBinder target = in.readStrongBinder();
      return target != null ? new Messenger(target) : null;
    }

    public Messenger[] newArray(int size) {
      return new Messenger[size];
    }
  };

  public static void writeMessengerOrNullToParcel(Messenger messenger,
      Parcel out) {
    out.writeStrongBinder(messenger != null ? messenger.mTarget.asBinder()
        : null);
  }

  public static Messenger readMessengerOrNullFromParcel(Parcel in) {
    IBinder b = in.readStrongBinder();
    return b != null ? new Messenger(b) : null;
  }

  public Messenger(IBinder target) {
    mTarget = IMessenger.Stub.asInterface(target);
  }
}

首先我们需要新建一个Service来处理客户端的请求,同时声明一个Handler作为参数来创建一个Messenger,然后通过getBinder()方法返回Binder。

public class MessageService extends Service {

  private Messenger mMessenger = new Messenger(new Handler() {
    @Override
    public void handleMessage(Message msgFromClient) {
      super.handleMessage(msgFromClient);
      Message msgToTarget = Message.obtain(msgFromClient);
      msgToTarget.what = 0;
      try {
        Thread.sleep(2000);
        msgToTarget.arg1 = msgFromClient.arg1 + msgFromClient.arg2;
        msgFromClient.replyTo.send(msgToTarget);
      } catch (InterruptedException e) {
        e.printStackTrace();
      } catch (RemoteException e) {
        e.printStackTrace();
      }
    }
  });

  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
    return mMessenger.getBinder();
  }
}

里面的逻辑是简单的将客户端传来的Message中的arg1和arg2的值相加并将结果返回给Message对应的replyTo这个Messenger,并通过send将服务端的Message返回给客户端。

然后在客户端处理:首先需要bindService来绑定这个Service,然后通过IBinder生成一个Messenger对象,这个Messenger对象就可以将需要处理的数据封装到Message然后send到Service去。

 Messenger mMessenger = new Messenger(new Handler() {
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      Log.w("Jayuchou", "--- 从异步线程中读取到数据 --- " + msg.arg1);
    }
  });

  Messenger mService;

  ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
      mService = new Messenger(service);
      Log.w("Jayuchou", "-- Connected success --");
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
      Log.w("Jayuchou", "-- Connected dismiss --");
      mService = null;
    }
  };

然后调用的地方方式为:

     Message msgFromClient = Message.obtain(null, 0, 1, 2);
        msgFromClient.replyTo = mMessenger;
        try {
          mService.send(msgFromClient);
        } catch (RemoteException e) {
          e.printStackTrace();
        }

将数据封装Message中,并且Message中的replyTo指定服务端中要将结果回调的Messenger对象。

msgFromClient.replyTo.send(msgToTarget);

我们可以看到Service中有这么一句代码,其中的replyTo就是我们在客户端传进去的Messenger,这时候调用send方法就可以将服务端的也就是另一个进程的数据传到想要用的进程然后采用Messenger进行接收,我们可以跟Handler用法类似的使用即可。Messenger是一个轻量级的AIDL,一次一个处理请求。

以上就是Android messenger 的消息处理的详解,关于Android 开发的文章,本站还很多,请大家搜索参阅,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2017-07-13

Android IPC机制利用Messenger实现跨进程通信

写作原因:跨进程通信的实现和理解是Android进阶中重要的一环.下面博主分享IPC一些相关知识.操作及自己在学习IPC过程中的一些理解.这一章使用Messenger实现跨进程通信,其中bindService基础部分参见Android IPC机制绑定Service实现本地通信. 跨进程简介 在介绍使用Messenger跨进程通信之前先要了解以下问题:为什么需要跨进程通信?只有有了需求才有学习的价值.我个人将不同进程简单的理解为不同的应用程序(当然也有例外,比如可以在同一个应用程序中开启两个或多个

android使用AIDL跨进程通信(IPC)

AIDL的作用 AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码.如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数. AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级.它是使用代理类在客户端和实现端传

Android IPC机制绑定Service实现本地通信

**写作原因:跨进程通信的实现和理解是Android进阶中重要的一环.下面博主分享IPC一些相关知识.操作及自己在学习IPC过程中的一些理解. 这一章是为下面的Messenger和AIDL的使用做准备,主要讲解Android Service的绑定和Activity与本地Service之间通信相关知识.** 简介 我们都知道启动Service有两种方式:startService()和bindService().相比第一种方式,bindService()能够更加灵活地实现与启动端Activity的数

Android AIDL实现跨进程通信的示例代码

AIDL是Android接口定义语言,它可以用于让某个Service与多个应用程序组件之间进行跨进程通信,从而可以实现多个应用程序共享同一个Service的功能. 实现步骤 例:用 A程序去访问 B程序的MyService.java服务 在B中建立AIDL文件MyAidlService.AIDL,在AIDL文件里写我们的接口方法 在MyService中写AIDL文件定义的方法的具体服务逻辑 在B的manifest文件中,为Service添加action "com.xyb.servicetest.

Android编程实现AIDL(跨进程通信)的方法详解

本文实例讲述了Android编程实现AIDL(跨进程通信)的方法.分享给大家供大家参考,具体如下: 一. 概述: 跨进程通信(AIDL),主要实现进程(应用)间数据共享功能. 二. 实现流程: 1. 服务器端实现: (1)目录结构,如下图: (2)实现*.aidl文件: A. IAIDLService.aidl实现: package com.focus.aidl; import com.focus.aidl.Person; interface IAIDLService { String getN

Android AIDL实现两个APP间的跨进程通信实例

本文为大家分享了Android AIDL实现两个APP间的跨进程通信实例,供大家参考,具体内容如下 1 Service端创建 首先需要创建一个Android工程然后创建AIDL文件,创建AIDL文件主要为了生成继承了Binder的Stub类,以便应用Binder进行进程间通信 servier端结构如下 AIDL代码如下 // IBookManager.aidl package com.example.bookserver.aidl; // Declare any non-default type

WinForm实现跨进程通信的方法

本文实例展示了WinForm实现跨进程通信的方法,分享给大家供大家参考之用.具体方法如下: 主要功能代码如下: public class WinMessageHelper { private struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } //使用COPYDATA进行跨进程通信 public const

AJAX机制详解以及跨域通信

1.Ajax 1.1.Ajax简介   Ajax简介这一部分我们主要是谈一下ajax的起源,ajax是什么?因为这些是跟技术无关的.所以,大多细节都是一笔带过. Ajax的起源? Ajax一词源于2005年 Jesse James Garrett发表的一篇题为"Ajax:A new Approach to Web Applications".他在这篇文       章中介绍了一种新技术,用他的话说,就是Ajax :Asynchronous JavaScript +XML的缩写. Aja

Android IPC机制ACtivity绑定Service通信代码实例

Binder通信过程类似于TCP/IP服务连接过程binder四大架构Server(服务器),Client(客户端),ServiceManager(DNS)以及Binder驱动(路由器) 其中Server,Client,ServiceManager运行于用户空间,驱动运行于内核空间.这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,SMgr是域名服务器(DNS),驱动是路由器. book.java package com.example.android_binder_t