天天看点

Messenger:使用消息的跨进程通信

messenger:信使

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

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

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

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

一般使用方法如下:

1。远程通过

java代码

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信

mmessenger = new messenger(mhandler)

创建一个信使对象

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

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

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信

return mmessenger.getbinder();

4.客户端使用远程返回的bindler得到一个信使(即得到远程信使)

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信

public void onserviceconnected(componentname name, ibinder service) {

rmessenger = new messenger(service);

     ......

}

这里虽然是new了一个messenger,但我们查看它的实现

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
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)前通过msm.replyto = mmessenger将自己的信使设置到消息中,这样服务端接收到消息时同时也得到了客户端的信使对象了,然后服务端可以通过

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信

//得到客户端的信使对象,并向它发送消息

cmessenger = msg.replyto;

cmessenger.send(message);

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

双向通信宣告完成。

下面改写apidemos工程实现messenger通信

messengerservice.java

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信

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";

@override

public void ondestroy() {

// todo auto-generated method stub

log.i(tag, "ondestroy");

cmessenger = null;

super.ondestroy();

public boolean onunbind(intent intent) {

log.i(tag, "onunbind");

return super.onunbind(intent);

static final

int msg_register_client = 1;

int msg_unregister_client = 2;

int msg_set_value = 3;

private random random = new random();

private handler mhandler =

new handler() {

public void handlemessage(message msg) {

log.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);

} catch (remoteexception e) {

// todo auto-generated catch block

e.printstacktrace();

break;

default:

super.handlemessage(msg);

};

* 自己的信使对象

private messenger mmessenger =

new messenger(mhandler);

* 客户的信使

private messenger cmessenger;

public ibinder onbind(intent intent) {

log.i(tag, "onbind");

//返回自己信使的bindler,以供客户端通过这个bindler得到服务端的信使对象(通过new messenger(bindler))

public void onrebind(intent intent) {

log.i(tag, "onrebind");

messengerserviceactivities.java

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信

import com.xwangly.apidemo.r;

import android.app.activity;

import android.content.componentname;

import android.content.serviceconnection;

import android.os.bundle;

import android.view.view;

import android.widget.textview;

public class messengerserviceactivities {

public static

class binding extends activity

implements

view.onclicklistener {

private string tag = "binding";

textview mcallbacktext;

private boolean isbound;

protected void oncreate(bundle savedinstancestate) {

super.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.");

case messengerservice.msg_set_value:

mcallbacktext.settext("received from service: " + msg.arg1);

* 自己的信使

private messenger mmessenger;

* 远程服务的信使

private messenger rmessenger;

private serviceconnection connection =

new serviceconnection() {

log.i(tag, "onserviceconnected");

mmessenger = new messenger(mhandler);

sendmessage();

public void onservicedisconnected(componentname name) {

rmessenger = null;

public void onclick(view v) {

intent 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 {

case r.id.unbind:

if (isbound) {

unbindservice(connection);

isbound = false;

* 使用服务端的信使向它发送一个消息。

private void sendmessage() {

message message = message.obtain(null, messengerservice.msg_set_value);

message.replyto = mmessenger;

rmessenger.send(message);

androidmanifest.xml相关配置如下:

xml代码

Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信
Messenger:使用消息的跨进程通信

<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">

android:name="android.intent.action.main"

<category

android:name="android.intent.category.launcher"

</activity>

至于layout就不帖了,两个按钮一个文本域。

继续阅读