认识Messenger

2024-05-27 01:48
文章标签 认识 messenger

本文主要是介绍认识Messenger,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【Messenger】
==================================================
@概述:
·实现跨进程的Handler消息传递和处理;
·其实现原理与AIDL相同,即绑定远程Service,跨进程获得Binder对象,进而实现通信;
·相比AIDL的优势为,Messenger可以通过Message和Bundle实现【对象型参数】的跨进程传递;
----------------------------------------
@注意事项:
·绑定远程服务的意图,必须指定包名;
·使用Messenger发送消息时,字符串和对象必须放在Bundle中;
·如须发送对象,对象类必须要实现Serializable接口;
·如须发送对象,则服客两端对象类的包名和内容都必须一致;
----------------------------------------
@服务端开发流程:
·定义Service,在初始化时,定义Messenger对象,在其内置Handler中实现客户端消息处理逻辑:
    @Override
    public void onCreate() {
        super.onCreate();
        /**
         * 初始化服务端信使(将来往家里送信),内置Handler用于处理来信
         */
        sMessenger = new Messenger(new Handler() {
            @Override
            public void handleMessage(Message msg) {


                //处理客户端消息
                int arg1 = msg.arg1;
                int arg2 = msg.arg2;
                Bundle cBundle = msg.getData();
                String str = cBundle.getString("string");
                User cUser = (User) cBundle.getSerializable("serializable");
                Log.d(TAG, "收到客户端来信:1/2/s/u" + arg1 + "/" + arg2 + "/" + str + "/" + cUser);


                //使用客户端信使回信
                cMessenger = msg.replyTo;//取出客户端Messenger
                Message replyMsg = Message.obtain();
                replyMsg.arg1 = arg1 + arg2;
                Bundle bundle = new Bundle();
                bundle.putString("string", "this is reply from server");
                bundle.putSerializable("serializable", new User("serverGirl", 20));
                replyMsg.setData(bundle);


                try {
                    cMessenger.send(replyMsg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }


·在onBind方法中返回本地Messenger对象的内置Binder:
    @Override
    public IBinder onBind(Intent intent) {
        return sMessenger.getBinder();//将我方信使的Binder的返回给远程应用,远程应用可以通过该Binder还原出sMessenger(代理)
    }


·如须向客户端发送回复消息,可以从客户端Message中获取客户端Messenger,并用其发送回复消息:
        sMessenger = new Messenger(new Handler() {
            @Override
            public void handleMessage(Message msg) {


                //处理客户端消息
...


                //使用客户端信使回信
                cMessenger = msg.replyTo;//取出客户端Messenger
                Message replyMsg = Message.obtain();
                replyMsg.arg1 = arg1 + arg2;
...


                try {
                    cMessenger.send(replyMsg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });


----------------------------------------
@客户端开发流程:
·绑定远程服务:
Intent intent = new Intent("com.mobiletrain.messenger.action.myservice");
        intent.setPackage("com.mobiletrain.messenger");//包名是必须的!
        bindService(intent, conn,BIND_AUTO_CREATE);


·在ServiceConnnection对象中获取服务端Binder对象,并用其构造向服务端发送消息的Messenger:
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            sMessenger = new Messenger(binder);//还原服务端信使
            Toast.makeText(MainActivity.this, "远程服务连接成功!", Toast.LENGTH_SHORT).show();
        }


        @Override
        public void onServiceDisconnected(ComponentName name) {
            Toast.makeText(MainActivity.this, "远程服务异常断开!", Toast.LENGTH_SHORT).show();
        }
    };


·使用构造好的服务端Messenger向服务端发送消息,消息的replyTo设置为我方Messenger:
        Message message = Message.obtain();
        message.replyTo = cMessenger;//植入我方信使
        message.arg1 = 56;
        message.arg2 = 78;
        Bundle bundle = new Bundle();
        bundle.putString("string", "this is msg from client");
        bundle.putSerializable("serializable", new User("clientBoy", 30));
        message.setData(bundle);


        try {
            sMessenger.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }




·创建我方Messenger实例,并在其内置Handler中实现消息处理逻辑,将来用于处理服务端发来的消息:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = ((TextView) findViewById(R.id.tv));


        cMessenger = new Messenger(new Handler(){
            @Override
            public void handleMessage(Message msg) {
                //处理服务端来信
                int sum = msg.arg1;
                tv.setText("服务端结果:"+sum);


                Bundle bundle = msg.getData();
                String str = bundle.getString("string");
                User user = (User) bundle.getSerializable("serializable");
                Toast.makeText(MainActivity.this, str+"/"+user, Toast.LENGTH_LONG).show();
            }
        });
    }

这篇关于认识Messenger的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006190

相关文章

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

每天认识几个maven依赖(ActiveMQ+activemq-jaxb+activesoap+activespace+adarwin)

八、ActiveMQ 1、是什么? ActiveMQ 是一个开源的消息中间件(Message Broker),由 Apache 软件基金会开发和维护。它实现了 Java 消息服务(Java Message Service, JMS)规范,并支持多种消息传递协议,包括 AMQP、MQTT 和 OpenWire 等。 2、有什么用? 可靠性:ActiveMQ 提供了消息持久性和事务支持,确保消

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

SpringMVC-1.认识及配置

SpringMVC是一个基于请求驱动的Web框架,和structs一样是目前最优秀的基于MVC框架,现在的项目一般都使用SpringMVC代替Structs。 MVC模式中,Model是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象在数据库中存取数据。View是应用程序中处理数据显示的部分,通常视图是依据模型数据创建。Controller是应用程序中处理用户交互的部分。通常控制器负责从视

【H2O2|全栈】关于HTML(1)认识HTML

HTML相关知识 目录 前言 准备工作 WEB前端是什么? HTML是什么? 如何运行HTML文件? 标签 概念 分类 双标签和单标签 行内标签和块标签 HTML文档结构 预告和回顾 UI设计相关 Markdown | Md文档相关  项目合作管理相关  后话 前言 本系列的博客将分享前端HTML的相关知识点。 本篇作为本系列的第一期博客,主要讲解H

认识鬼火引擎

一、Irrlicht简介 (1)概念Irrlicht引擎是一个用C++书写的高性能实时3D引擎,可以应用于C++程序或者.NET语言中。通过使用Direct3D(Windows平台)、OpenGL 或它自己的软件着色程序,可以实现该引的完​全跨平台。尽管是开源的,该Irrlicht库提供了可以在商业级的3D引擎上具有的艺术特性,例如动态的阴影,粒子系统,角色动画,室内和室外技术以及碰撞检测等。(

Jenkins--pipeline认识及与RF文件的结合应用

什么是pipeline? Pipeline,就是可运行在Jenkins上的工作流框架,将原本独立运行的单个或多个节点任务连接起来,实现单个任务难以完成的复杂流程编排与可视化。 为什么要使用pipeline? 1.流程可视化显示 2.可自定义流程任务 3.所有步骤代码化实现 如何使用pipeline 首先需要安装pipeline插件: 流水线有声明式和脚本式的流水线语法 流水线结构介绍 Node:

git:认识git和基本操作(1)

目录 一、版本控制器 1.安装git 2.创建git本地仓库 3.配置git 二、git操作(1) 1.工作区、暂存区、版本库 2.添加文件 3.查看.git 4.修改文件 一、版本控制器         所谓的版本控制器,就是能让你了解到每一个文件的修改历史。相应的,在企业级开发中,用来记录一个工程的每一次改动和管理版本迭代,同时方便多人协作开发。         g

关于MANIFEST.MF的内容认识

文章来源 https://baike.baidu.com/item/MANIFEST.MF https://www.cnblogs.com/Gandy/p/7290069.html 一、百度百科关于MANIFEST.MF文件介绍 打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录,这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了

C++---由优先级队列认识仿函数

文章目录 一、优先级队列是什么? 二、如何使用优先级队列 1、优先级队列容器用法 2、为什么容器本身无序? 三、什么是仿函数? 1. 什么是仿函数? 2. 仿函数的优势 四、仿函数如何使用? 1、重载operator()函数 2、运用第三个参数模板 3、大小堆切换  大堆测试代码: 小堆测试代码: 4、头文件总代码  五、什么是容器适配器? 前言   本文主要介绍了优先级队列是什