Android中通过Messenger与Service实现进程间双向通信.docx

上传人:b****5 文档编号:2775979 上传时间:2022-11-15 格式:DOCX 页数:13 大小:188.48KB
下载 相关 举报
Android中通过Messenger与Service实现进程间双向通信.docx_第1页
第1页 / 共13页
Android中通过Messenger与Service实现进程间双向通信.docx_第2页
第2页 / 共13页
Android中通过Messenger与Service实现进程间双向通信.docx_第3页
第3页 / 共13页
Android中通过Messenger与Service实现进程间双向通信.docx_第4页
第4页 / 共13页
Android中通过Messenger与Service实现进程间双向通信.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

Android中通过Messenger与Service实现进程间双向通信.docx

《Android中通过Messenger与Service实现进程间双向通信.docx》由会员分享,可在线阅读,更多相关《Android中通过Messenger与Service实现进程间双向通信.docx(13页珍藏版)》请在冰豆网上搜索。

Android中通过Messenger与Service实现进程间双向通信.docx

Android中通过Messenger与Service实现进程间双向通信

Android中通过Messenger与Service实现进程间双向通信

Android中的Service和其调用者既可以在同一个App中,也可以在不同的App。

如果Service在App1中,而调用Service的客户端在App2中,那么我们就可以用Service实现进程间的相互通信。

本文将介绍如何通过bindService和Messenger实现进程间通信(IPC),如果对bindService绑定服务和Binder不熟悉,可参见《Android中bindService的使用及Service生命周期》,理解该博文是本文的基础。

让Service实现与其他进程通信的关键是Messenger,以及与其相关的IBinder和Hanlder。

如果对Handler不熟悉,可参见《Android中Handler的使用》。

Messenger使用步骤

以下是如何使用Messenger的步骤:

1.Service需要实现一个Hanlder,用以处理从客户端收到的消息

2.用该Handler创建一个Messenger对象,Messenger对象内部会引用该Handler对象

3.用创建好的Messenger对象获得一个IBinder实例,并且将该IBinder通过Service的onBind方法返回给各个客户端

4.客户端通过收到的IBinder对象实例化一个Messenger对象,该Messenger内部指向指向Service中的Handler。

客户端通过该Messenger对象就可以向Service中的Hanlder发送消息。

5.Service中的Hanlder收到消息后,在Handler中的handleMessage方法中处理消息。

6.通过上面的第4步与第5步,就完成了客户端向Service发送消息并且Service接收到消息的单向通信过程,即客户端->Service。

如果要实现Service向客户端回消息的通信过程,即Service->客户端,那么前提是在客户端中也需要像Service一样内部维护有一个指向Handler的Messenger。

当在第四步中客户端向Service发送信息时,将Message的replyTo属性设置为客户端自己的Messenger。

这样在第5步Service在Handler的handleMessage中处理收到的消息时,可以通过Message的Messenger再向客户端发送Message,这样客户端内维护的Handler对象就会收到来自于Service的Message,从而完成Service向客户端发送消息且客户端接收到消息的通信过程。

综上六步就能完成客户端与Service的跨进程双向通信过程:

客户端->Service->客户端

为了演示客户端与Service的跨进程通信,我建立了两个应用ClientApp和ServiceApp,两个应用的名称也是见名知意:

1.ClientApp,该App是客户端,用于调用服务

2.ServiceApp,该App是Service端,用于供客户端ClientApp调用

Service代码

ServiceApp中只有一个MyService类,没有其他Activity,也就是说ServiceApp没有任何UI界面。

ServiceApp的manifest.xml文件如下所示:

xmlversion="1.0"encoding="utf-8"?

>

android="

package="com.ispring2.serviceapp">

android:

allowBackup="true"

android:

icon="@drawable/ic_launcher"

android:

label="ServiceApp">

android:

name=".MyService"

android:

enabled="true"

android:

exported="true">

name="com.ispring2.action.MYSERVICE"/>

name="android.intent.category.DEFAULT"/>

我们在ServiceApp的manifest.xml文件中注册了MyService,并通过exported=”true”将其声明为可被其他App调用的。

需要注意的是,我们将其action设置为自定义的action(com.ispring2.action.MYSERVICE),这是为了方便客户端通过其action启动MyService。

并且我们将其设置了值为android.intent.category.DEFAULT的category。

ServiceApp中MyService的代码如下所示:

packagecom.ispring2.serviceapp;

importandroid.app.Service;

importandroid.content.Intent;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.IBinder;

importandroid.os.Message;

importandroid.os.Messenger;

importandroid.os.RemoteException;

importandroid.util.Log;

publicclassMyServiceextendsService{

privatestaticfinalintRECEIVE_MESSAGE_CODE=0x0001;

privatestaticfinalintSEND_MESSAGE_CODE=0x0002;

//clientMessenger表示的是客户端的Messenger,可以通过来自于客户端的Message的replyTo属性获得,

//其内部指向了客户端的ClientHandler实例,可以用clientMessenger向客户端发送消息

privateMessengerclientMessenger=null;

//serviceMessenger是Service自身的Messenger,其内部指向了ServiceHandler的实例

//客户端可以通过IBinder构建Service端的Messenger,从而向Service发送消息,

//并由ServiceHandler接收并处理来自于客户端的消息

privateMessengerserviceMessenger=newMessenger(newServiceHandler());

//MyService用ServiceHandler接收并处理来自于客户端的消息

privateclassServiceHandlerextendsHandler{

@Override

publicvoidhandleMessage(Messagemsg){

Log.i("DemoLog","ServiceHandler->handleMessage");

if(msg.what==RECEIVE_MESSAGE_CODE){

Bundledata=msg.getData();

if(data!

=null){

Stringstr=data.getString("msg");

Log.i("DemoLog","MyService收到客户端如下信息:

"+str);

}

//通过Message的replyTo获取到客户端自身的Messenger,

//Service可以通过它向客户端发送消息

clientMessenger=msg.replyTo;

if(clientMessenger!

=null){

Log.i("DemoLog","MyService向客户端回信");

MessagemsgToClient=Message.obtain();

msgToClient.what=SEND_MESSAGE_CODE;

//可以通过Bundle发送跨进程的信息

Bundlebundle=newBundle();

bundle.putString("msg","你好,客户端,我是MyService");

msgToClient.setData(bundle);

try{

clientMessenger.send(msgToClient);

}catch(RemoteExceptione){

e.printStackTrace();

Log.e("DemoLog","MyService向客户端发送信息失败:

"+e.getMessage());

}

}

}

}

}

@Override

publicvoidonCreate(){

Log.i("DemoLog","MyService->onCreate");

super.onCreate();

}

@Override

publicIBinderonBind(Intentintent){

Log.i("DemoLog","MyServivce->onBind");

//获取Service自身Messenger所对应的IBinder,并将其发送共享给所有客户端

returnserviceMessenger.getBinder();

}

@Override

publicvoidonDestroy(){

Log.i("DemoLog","MyService->onDestroy");

clientMessenger=null;

super.onDestroy();

}

}

MyService中有一个内部类ServiceHandler,继承自Hanlder并重写了handleMessage方法,MyService用ServiceHandler接收并处理来自于客户端的消息。

MyService中,我们用ServiceHandler的实例初始化了serviceMessenger。

serviceMessenger是Service自身的Messenger,其内部指向了ServiceHandler的实例,客户端可以通过IBinder构建Service端的Messenger,从而向Service发送消息,并由ServiceHandler接收并处理来自于客户端的消息。

客户端代码

客户端应用ClientApp就一个MainActivity,其界面上就只有两个按钮:

bindService和unbindService,界面如下:

代码如下所示:

packagecom.ispring.clientapp;

importandroid.app.Activity;

importandroid.content.C

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1