android bound service,Android Service详解(七)---绑定服务BoundService详解之Messenger双向通信的实现...

这是第七篇文章主要讲的是BoundService中用Messenger实现IPC。

前三篇文章对扩展Binder类和AIDL进行了说明,绑定服务一般通过AIDL和Messenger来实现IPC

一、概述

Messenger实现IPC通信,底层也是使用了AIDL方式。和AIDL方式不同的是,  Messenger方式是利用Handler形式处理,因此,它是线程安全的,这也表示它不支持并发处理;而AIDL方式是非线程安全的,支持并发处理,因此,我们使用,AIDL方式时需要保证代码的线程安全。

大部分情况下, 我们应用中不需要并发处理。 因此, 我们通常只需要使用Messenger方式。

思想:在进程A中创建一个Message,将这个Message对象通过Messenger.send(message)方法传递到进程B(当然, Message对象本身是无法被传递到进程B的, send(message)方法会使用一个Parcel对象对Message对象编集,再将Parcel对象传递到进程B中,然后解编集,得到一个和进程,A中Message对象内容一样的对象) ,再把Message对象加入到进程B的消息队列里, Handler会去处理它。

二、具体步骤,双向通信的实现

1.首先创建一个Service服务,并实现一个 Handler,由其接收来自客户端的每个调用的回调

(这个是接收时的代码)class IncomingHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MSG_SAY_HELLO:

Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();

System.out.println(msg.getData().getString("info"));

break;

default:

super.handleMessage(msg);

}

}

}

(实现双向通信的代码,接收后发送给客户端)class IncomingHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MSG_SAY_HELLO:

Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();

System.out.println(msg.getData().getString("info"));

//实现双向通讯

Messenger client = msg.replyTo;

Message replyMessage = Message.obtain(null, MSG_SAY_HELLO);

for(int i = 0;i<20;i++){

try {

Thread.sleep(500);

Bundle bundle = new Bundle();

bundle.putString("reply", "嗯嗯,我已经收到你的第"+i+"条信息,稍后回复你。");

replyMessage.setData(bundle);

try {

client.send(replyMessage);

} catch (RemoteException e) {

e.printStackTrace();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

break;

default:

super.handleMessage(msg);

}

}

}

2.Handler 用于创建 Messenger 对象(对 Handler 的引用)final Messenger mMessenger = new Messenger(new IncomingHandler());

3.Messenger 创建一个 IBinder,服务通过 onBind() 使其返回客户端@Override

public IBinder onBind(Intent intent) {

Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();

return mMessenger.getBinder();

}

4.上述完整代码public class MessengerService extends Service {

/** Command to the service to display a message */

static final int MSG_SAY_HELLO = 1;

/**

* Handler of incoming messages from clients.

*/

class IncomingHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MSG_SAY_HELLO:

Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();

System.out.println(msg.getData().getString("info"));

//实现双向通讯

Messenger client = msg.replyTo;

Message replyMessage = Message.obtain(null, MSG_SAY_HELLO);

for(int i = 0;i<20;i++){

try {

Thread.sleep(500);

Bundle bundle = new Bundle();

bundle.putString("reply", "嗯嗯,我已经收到你的第"+i+"条信息,稍后回复你。");

replyMessage.setData(bundle);

try {

client.send(replyMessage);

} catch (RemoteException e) {

e.printStackTrace();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

break;

default:

super.handleMessage(msg);

}

}

}

/**

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

*/

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

/**

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

* for sending messages to the service.

*/

@Override

public IBinder onBind(Intent intent) {

Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();

return mMessenger.getBinder();

}

}

5.客户端使用 IBinder 将 Messenger(引用服务的 Handler)实例化,然后使用后者将 Message 对象发送给服务

(1)定义一个Messenger对象,Messenger mService = null;并在绑定成功后实例化public void onServiceConnected(ComponentName className, IBinder service) {

// This is called when the connection with the service has been

// established, giving us the object we can use to

// interact with the service.  We are communicating with the

// service using a Messenger, so here we get a client-side

// representation of that from the raw IBinder object.

mService = new Messenger(service);

mBound = true;

}

(2)声明一个Handler用来处理服务端的数据private class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MessengerService.MSG_SAY_HELLO:

System.out.println("receive from Service:" + msg.getData().get("reply"));

TextView textView = new TextView(getApplicationContext());

textView.setTextColor(Color.BLACK);

textView.setText("receive from Service:" + msg.getData().get("reply"));

linearLayout.addView(textView);

break;

default:

super.handleMessage(msg);

}

}

}

(3)声明一个Messenger对象public void sayHello(View v) {

if (!mBound) return;

// Create and send a message to the service, using a supported 'what' value

Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);

Bundle bundle = new Bundle();

bundle.putString("info","呵呵哒");

msg.setData(bundle);

msg.replyTo = mGetReplyMessenger;

try {

mService.send(msg);

} catch (RemoteException e) {

e.printStackTrace();

}

}

并用msg.replyTo得到Messenger实例

至此绑定服务就基本结束了。

附上源码:源码

Android Service详解系列

————————————————

原文链接:https://blog.csdn.net/superbiglw/article/details/53158164

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值