天天看點

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就不帖了,兩個按鈕一個文本域。

繼續閱讀