文档章节

Messenger实现Android IPC

Git_Android
 Git_Android
发布于 2015/05/16 19:07
字数 650
阅读 27
收藏 0

当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 0:
//执行相应的任务
                    delivered=true;
                    break;
                case 1:
//执行相应的任务

                    break;
            }
            Message reply=Message.obtain(null,2);//生成消息
            try {
                msg.replyTo.send(reply);//反馈消息
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            return true;
        }
    }
}
下例中,客户端首先绑定到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=0;
        Bundle bundle=new Bundle();
        bundle.putInt("key",1);
        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 2:
                    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接口。当然如果要传递类也必须实现该接口。

© 著作权归作者所有

下一篇: 多点触控
Git_Android
粉丝 0
博文 27
码字总数 16765
作品 0
宜昌
程序员
私信 提问
Android 使用Messenger跨进程通信框架

一.通过Binder绑定形式的通信 上一篇说道Binder机制的通信框架,也说过Messenger的底层实现自AIDL,因此对于跨进程通信中,Messenger是一种比较高级的框架,可以说对于一个app开发者来说重要性...

IamOkay
2014/12/04
0
0
[翻译]Android Bound Services

一个bound service是一个client-server接口中的server端。一个bound service允许应用组件(比如activities)bind到它,发送请求,接收响应,甚至是执行进程间通信(IPC)。一个bound service在典...

WolfCS
2014/03/23
0
0
一份关于 Java、Kotlin 与 Android 的学习笔记

JavaKotlinAndroidLearn 这是一份关于 Java 、Kotlin 、Android 的学习笔记,既包含对基础知识点的介绍,也包含对一些重要知识点的源码解析,笔记的大纲如下所示: Java 重拾Java(0)-基础知...

叶应是叶
2018/08/08
0
0
四大组件之Service(三)-Service的跨进程调用

版权声明:本文为博主原创文章,禁止转载,违者必究。 https://blog.csdn.net/anddlecn/article/details/51671035 第4节 远程调用 之前提到过:如果站在Service与触发Service运行的那个组件的...

anddlecn
2016/06/14
0
0
进程通信(IPC)之Messenger

bound服务是客户端-服务器模式的服务。 bound服务的创建方式之一: 创建一个支持绑定的服务时,你必须提供一个 IBinder,用作客户端和服务间进行通信的编程接口 使用Messenger定义该接口: ...

新根
2015/08/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenCv + ffmpeg + rtmp 实现摄像头采集数据直播功能

采用OpenCv获取图像数据,通过ffmpeg推流给rtmp服务器 OpenCV获取的图像数据为BGR格式,需要转换成YUV格式,再将其编码为h264格式,通过ffmpeg推流 头文件 extern "C"{#include <libavco...

cloudjx
30分钟前
1
0
服务器yum源更新为阿里云yum源

1 备份下原来的yum源 cd /etc/yum.repos.d/ mv CentOS-Base.repo CentOS-Base.repo_bak 1 2 3 2 获取阿里云yum源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/re......

Mr_Tea伯奕
38分钟前
0
0
CLEARTEXT communication to xxx not permitted by network security policy

Android P http网络请求不通,报出异常:java.net.UnknownServiceException: CLEARTEXT communication to xxxx not permitted by network security policy Google表示,为保证用户数据和设备......

醉雨
52分钟前
3
0
开发函数计算的正确姿势 —— 移植 next.js 服务端渲染框架

首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准...

阿里云云栖社区
今天
1
0
Windows获取其他进程中Edit控件的内容

最近做的MFC项目中,有个获取其他进程中Edit控件内容的需求,本来以为是个很简单的问题,但是来来回回折腾了不少时间,发博记录一下。   刚开始拿到这个问题,很自然的就想到GetDlgItemTex...

WinkJie
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部