展会信息港展会大全

Android Messenger 跨进程通信
来源:互联网   发布日期:2016-01-13 21:52:06   浏览:3224次  

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

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,但我们查看它的实现

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将自己的信使设置到消息中,这样服务端接收到消息时同时也得到了客户端的信使对象了,然后服务端可以通过/得到客户端的信使对象,并向它发送消息cMessenger = msg.replyTo;cMessenger.send(message);

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

双向通信宣告完成。

以下代码来自ApiDemo

Service code:

[java]

public class MessengerService extends Service {

/** For showing and hiding our notification. */

NotificationManager mNM;

/** Keeps track of all current registered clients. */

ArrayList<Messenger> mClients = new ArrayList<Messenger>();

/** Holds last value set by a client. */

int mValue = 0;

/**

* Command to the service to register a client, receiving callbacks

* from the service.The Message's replyTo field must be a Messenger of

* the client where callbacks should be sent.

*/

static final int MSG_REGISTER_CLIENT = 1;

/**

* Command to the service to unregister a client, ot stop receiving callbacks

* from the service.The Message's replyTo field must be a Messenger of

* the client as previously given with MSG_REGISTER_CLIENT.

*/

static final int MSG_UNREGISTER_CLIENT = 2;

/**

* Command to service to set a new value.This can be sent to the

* service to supply a new value, and will be sent by the service to

* any registered clients with the new value.

*/

static final int MSG_SET_VALUE = 3;

/**

* Handler of incoming messages from clients.

*/

class IncomingHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MSG_REGISTER_CLIENT:

mClients.add(msg.replyTo);

break;

case MSG_UNREGISTER_CLIENT:

mClients.remove(msg.replyTo);

break;

case MSG_SET_VALUE:

mValue = msg.arg1;

for (int i = mClients.size() - 1; i >= 0; i --) {

try {

mClients.get(i).send(Message.obtain(null,

MSG_SET_VALUE, mValue, 0));

} catch (RemoteException e) {

// The client is dead.Remove it from the list;

// we are going through the list from back to front

// so this is safe to do inside the loop.

mClients.remove(i);

}

}

break;

default:

super.handleMessage(msg);

}

}

}

/**

* Target we publish for clients to send messages to IncomingHandler.

*/

final Messenger mMessenger = new Messenger(new IncomingHandler());

@Override

public void onCreate() {

mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

// Display a notification about us starting.

showNotification();

}

@Override

public void onDestroy() {

// Cancel the persistent notification.

mNM.cancel(R.string.remote_service_started);

// Tell the user we stopped.

Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();

}

/**

* When binding to the service, we return an interface to our messenger

* for sending messages to the service.

*/

@Override

public IBinder onBind(Intent intent) {

return mMessenger.getBinder();

}

/**

* Show a notification while this service is running.

*/

private void showNotification() {

// In this sample, we'll use the same text for the ticker and the expanded notification

CharSequence text = getText(R.string.remote_service_started);

// Set the icon, scrolling text and timestamp

Notification notification = new Notification(R.drawable.stat_sample, text,

System.currentTimeMillis());

// The PendingIntent to launch our activity if the user selects this notification

PendingIntent contentIntent = PendingIntent.getActivity(this, 0,

new Intent(this, Controller.class), 0);

// Set the info for the views that show in the notification panel.

notification.setLatestEventInfo(this, getText(R.string.remote_service_label),

text, contentIntent);

// Send the notification.

// We use a string id because it is a unique number.We use it later to cancel.

mNM.notify(R.string.remote_service_started, notification);

}

}

赞助本站

人工智能实验室

相关热词: Messenger 跨进程通信

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港