当Service不需要支持并发操作时Messenger会非常有用。Messenger类使用Handler执行每个传入的消息,所有客户端的调用都按顺序运行在同一个线程上,这和AIDL是有区别的,AIDL每个客户端对应一个线程。使用Messenger类还能避免AIDL文件带来的问题,并可以方便地为客户端提供异步消息API。虽然没有那么强大,但该类有时候会很有效,因为它更容易在客户端和Service实现。

下面的例子展示了如何使用Messenger类来提供异步API。首先在onCreate()方法中创建Messenger,然后在onBind()方法中返回Binder对象。当Messenger接受到消息时,它使用存储在replyTo成员变量里的Messenger对象响应客户端的请求。

public class MessengerService extends Service {
private Handler mMessageHandler;
private Messenger mMessenger;
public MessengerService() {
} @Override
public IBinder onBind(Intent intent) {
return this.mMessenger.getBinder();
} @Override
public void onCreate() {
super.onCreate();
HandlerThread handlerThread=new HandlerThread("MessengerService");
handlerThread.start();
this.mMessageHandler=new Handler(handlerThread.getLooper(),new MyhandlerCallback());
this.mMessenger=new Messenger(this.mMessageHandler);
} @Override
public void onDestroy() {
super.onDestroy();
this.mMessageHandler.getLooper().quit();
} private class MyhandlerCallback implements Handler.Callback{
@Override
public boolean handleMessage(Message msg) {
boolean delivered=false;
switch (msg.what){
case :
//执行具体的任务
delivered=true;
break;
case :
//执行具体的任务
break;
}
Message reply=Message.obtain(null,);//生成消息
try {
msg.replyTo.send(reply);//反馈给客户端
} catch (RemoteException e) {
e.printStackTrace();
}
return true;
}
}
}
   服务器端配置文件代码如下:<service
android:name=".MessengerService"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.example.liyuanjing.myapplication.MESSENGER_SERVICE"/>
</intent-filter>
</service>

下例中,客户端首先绑定到Service,然后使用IBinder作为参数构建一个Messenger对象,作为运行在远程Service中的Messenager的代理。当向Service发送消息时,也可以设置Message对象的replyTo属性。

public class MainActivity extends Activity implements ServiceConnection {
private Button start;
private Messenger mRemoteMessenger;
private Messenger mReplyMessenger;
private Handler mReplyHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.start=(Button)findViewById(R.id.start);
HandlerThread handlerThread=new HandlerThread("ReplyMessenger");
handlerThread.start();
this.mReplyHandler=new Handler(handlerThread.getLooper(),new ReplyHandlerCallback());
this.mReplyMessenger=new Messenger(this.mReplyHandler);
} @Override
protected void onResume() {
super.onResume();
bindService(new Intent("com.example.liyuanjing.myapplication.MESSENGER_SERVICE"),this,BIND_AUTO_CREATE);
} @Override
protected void onPause() {
super.onPause();
unbindService(this);
} @Override
protected void onDestroy() {
super.onDestroy();
this.mReplyHandler.getLooper().quit();
} public void onSendTextPressed(View v){
Message message=Message.obtain();
message.what=;
Bundle bundle=new Bundle();
bundle.putInt("key",);
message.obj=bundle;
message.replyTo=mReplyMessenger;
try {
mRemoteMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
this.mRemoteMessenger=new Messenger(service);
this.start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onSendTextPressed(v);
}
});
} @Override
public void onServiceDisconnected(ComponentName name) {
this.mRemoteMessenger=null;
}
private class ReplyHandlerCallback implements Handler.Callback{
@Override
public boolean handleMessage(Message msg) {
switch (msg.what){
case :
Toast.makeText(MainActivity.this,"接受到了",Toast.LENGTH_LONG).show();
break;
}
return true;
}
}
}

注意必须用Bundle传递常规类型数据,否则会报错:

java.lang.RuntimeException: Can't marshal non-Parcelable objects across processes.

因为Binder事务传递的数据被称为包裹(Parcel),必须实现Parcelable接口,否则无法在两个应用之间进行通信。之所以用Bundle传递是因为该类实现了Parcelable接口。当然如果要传递类也必须实现该接口。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Messenger实现Android IPC的更多相关文章

  1. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- Messenger

    Messenger类实际是对Aidl方式的一层封装.本文只是对如何在Service中使用Messenger类实现与客户端的通信进行讲解,对Messenger的底层不做说明.阅读Android Prog ...

  2. android IPC通信(上)-sharedUserId&amp;&amp;Messenger

    看了一本书,上面有一章解说了IPC(Inter-Process Communication,进程间通信)通信.决定结合曾经的一篇博客android 两个应用之间的通信与调用和自己的理解来好好整理总结一 ...

  3. 【Android - IPC】之Messenger简介

    参考资料: 1.<Android开发艺术探索>第二章2.4.3 2.[Messenger完全解析] 1.Messenger概述 Messenger,译为“信使”,是Android中一种基于 ...

  4. Android IPC机制之Messenger

    Messenger:两个进程通过Messenger传递消息,进程1和进程2中都需要创建一个Messenger,创建过程:首先进程2需要创建一个服务, 并在服务中创建一个Messenger对象,进程1通 ...

  5. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper

    前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...

  6. Android IPC 结篇

    一.概述 Android 的 IPC 方式有 Bundle .共享文件.AIDL .Messenger .ContentProvider .Socket ,我们在实现进程间通信时要选择哪一种方式来实现 ...

  7. Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

    在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...

  8. android IPC 进程间通讯

    参考资料: http://blog.csdn.net/birdsaction/article/details/39451849 在这里我说一下学习技术的方法,别人的博客,别人的东西,再简单,自己没有写 ...

  9. 【Android - IPC】之Binder机制简介

    参考资料: 1.<Android开发艺术探索>第二章2.3.3 Binder 2.[Android Binder设计与实现-设计篇] 3.[Android Binder机制介绍] 1. 什 ...

随机推荐

  1. 简谈 JavaScript、Java 中链式方法调用大致实现原理

    相信,在 JavaScript .C# 中都见过不少链式方法调用,那么,其中实现该类链式调用原理,大家有没有仔细思考过?其中 JavaScript 类库:jQuery 中就存在大量例子,而在 C# 中 ...

  2. 【M26】限制某个class所能产生的对象数量

    1.每当产生一个对象,必定调用构造方法.因此,禁止产生对象的做法就是,将所有的构造方法声明为private. 2.只有在类的内部才可以访问private成员,有两层含义:在类的内部可以访问this的p ...

  3. C#文件读写常用类介绍

    首先要熟悉.NET中处理文件和文件夹的操作.File类和Directory类是其中最主要的两个类.了解它们将对后面功能的实现提供很大的便利.      本节先对和文件系统相关的两个.NET类进行简要介 ...

  4. Oracle使用goldengate分别向Oracle和mysql双路的单向复制

    一.Oracle分别向Oracle和mysql双路的单向复制是在: ORACLE-mysql的单向复制基础上做的.http://blog.csdn.net/q947817003/article/det ...

  5. 从零开始学习Hadoop--第1章 Hadoop的安装

    Hadoop的安装比较繁琐,有如下几个原因:其一,Hadoop有非常多的版本:其二,官方文档不尽详细,有时候更新脱节,Hadoop发展的太快了:其三,网上流传的各种文档,或者是根据某些需求定制,或者加 ...

  6. delphi execCommand

    WebBrowser1.Document as IHTMLDocument2 关键点 function execCommand(const cmdID: WideString; showUI: Wor ...

  7. ListView返回选中的多项目

    ListView返回选中的多项目     procedure TForm1.Button3Click(Sender: TObject);var  s: string;  I: Integer;begi ...

  8. MySQL server version for the right syntax to use near ‘USING BTREE

    转自:http://www.douban.com/note/157818842/ 有时导入mysql会提示如下错误: C:\Users\liqiang>mysql -uroot -paaaaaa ...

  9. iOS开发——数据持久化Swift篇&文件目录路径获取(Home目录,文档目录,缓存目录等)

    文件目录路径获取(Home目录,文档目录,缓存目录等)   iOS应用程序只能在自己的目录下进行文件的操作,不可以访问其他的存储空间,此区域被称为沙盒.下面介绍常用的程序文件夹目录:   1,Home ...

  10. 解决Mac下SublimeLinter的Unsafe Characters警告

    Mac下编辑JS文件, 如果是中文字符的行会警告: This character may get silently deleted by one or more browsers. SublimeLi ...