Android 跨进程通信并传输复杂数据

news2024/11/24 3:10:17

前言
AIDL (Android Interface Definition Language) 支持以下数据类型:
基本数据类型:int、long、float、double、boolean、char、byte。
字符串类型:String。
集合类型:List、Map、Set。
Parcelable 类型:实现了 Parcelable 接口的自定义类。
IBinder 类型:用于跨进程通信的 Binder 类型。
数组类型:int[]、String[]、Parcelable[] 等。
其他类型:CharSequence、SparseArray、Bundle、CharSequence[]、ArrayList 等。
所以,传输复杂类型的时候,只能使用Parcelable ,不支持Serializable

服务端

  • 1、创建接收数据AIDL 文件
// IServerInterface.aidl
package com.rayvison.socketserviceapp;
import com.rayvison.socketserviceapp.ComplexData;
// Declare any non-default types here with import statements

interface IServerInterface {

void simpleData(String msg);
void complexData(in ComplexData complexData);
void destroyService();
void unregisterListener(com.rayvison.socketserviceapp.ICallBackInterface listener);
void registerListener(com.rayvison.socketserviceapp.ICallBackInterface listener);
}
  • 2、创建接收接口AIDL 文件
// ICallBackInterface.aidl
package com.rayvison.socketserviceapp;
import com.rayvison.socketserviceapp.ComplexData;
// Declare any non-default types here with import statements

interface ICallBackInterface {
   void onSimpleData(String msg);

    void onComplexData(in ComplexData complexData);
}
  • 3、创建实体类以及实体类AIDL 文件

实体类:

package com.rayvison.socketserviceapp;

import android.os.Parcel;
import android.os.Parcelable;



public class ComplexData implements Parcelable {

    private float[][]handValue;
   public ComplexData(){}
    protected ComplexData(Parcel in) {
        handValue = new float[in.readInt()][in.readInt()];
        for (int i = 0; i < handValue.length; i++) {
            in.readFloatArray(handValue[i]);
        }
    }


    public void setData(float[][] leftHandValue) {
        this.handValue = leftHandValue;
    }

    public float[][] getData() {
        return handValue;
    }

    public static final Creator<ComplexData> CREATOR = new Creator<ComplexData>() {
        @Override
        public ComplexData createFromParcel(Parcel in) {
            return new ComplexData(in);
        }

        @Override
        public ComplexData[] newArray(int size) {
            return new ComplexData[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(handValue.length);
        dest.writeInt(handValue[0].length);
        for (int i = 0; i < handValue.length; i++) {
            dest.writeFloatArray(handValue[i]);
        }


    }
}


// ComplexData.aidl
package com.rayvison.socketserviceapp;

// Declare any non-default types here with import statements

parcelable   ComplexData;
  • 4、创建binder
package com.rayvison.socketserviceapp.server;

import android.os.RemoteCallbackList;
import android.os.RemoteException;

import com.rayvison.socketserviceapp.ComplexData;
import com.rayvison.socketserviceapp.ICallBackInterface;
import com.rayvison.socketserviceapp.IServerInterface;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LocalBinder  extends IServerInterface.Stub {


    private  ConnectServer server;

    public  LocalBinder(ConnectServer connectService){
        this.server=connectService;
    }
    private RemoteCallbackList<ICallBackInterface> mRemoteCallbackList = new RemoteCallbackList();
    private Lock mLock = new ReentrantLock();


    @Override
    public void simpleData(String msg) throws RemoteException {
        mLock.lock();
        int i = 0;
        try {
            i = mRemoteCallbackList.beginBroadcast();
            for (int j = 0; j < i; j++) {
                mRemoteCallbackList.getBroadcastItem(j).onSimpleData(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mRemoteCallbackList.finishBroadcast();
            mLock.unlock();
        }
    }

    @Override
    public void complexData(ComplexData complexData) throws RemoteException {
        mLock.lock();
        try {
            int i = mRemoteCallbackList.beginBroadcast();
            for (int j = 0; j < i; j++) {
                mRemoteCallbackList.getBroadcastItem(j).onComplexData(complexData);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        } finally {
            mRemoteCallbackList.finishBroadcast();
            mLock.unlock();
        }
    }

    @Override
    public void destroyService() throws RemoteException {

    }

    @Override
    public void unregisterListener(ICallBackInterface listener) throws RemoteException {
        mRemoteCallbackList.unregister(listener);
    }

    @Override
    public void registerListener(ICallBackInterface listener) throws RemoteException {
        mRemoteCallbackList.register(listener);
    }
}

客户端

  • 1、拷贝aidl 整个文件夹到main 目录下

  • 在这里插入图片描述

  • 2、拷贝数据类完整路径到java 下
    在这里插入图片描述

  • 3、启动服务,开始通信

(1) 绑定服务

 fun bindService() {
        val intent = Intent()
        intent.setPackage("com.rayvison.socketserviceapp")
        intent.action = "com.sockets.server.Connect"
        bindService(intent, mConnection, BIND_AUTO_CREATE)
    }

(2)客户端向服务器发送复杂数据

  fun sendComplexDataToServer() {
        val complexData = ComplexData()
        complexData.data = leftHandValue1
        mBinder?.complexData(complexData)
    }

(3)服务器向客户端应答返回简单数据响应

   @Override
    public void complexData(ComplexData complexData) throws RemoteException {
        mLock.lock();
        try {
            int i = mRemoteCallbackList.beginBroadcast();
            for (int j = 0; j < i; j++) {
                //服务器收到消息,发送一条回复
                mRemoteCallbackList.getBroadcastItem(j).onSimpleData("收到消息");
                mRemoteCallbackList.getBroadcastItem(j).onComplexData(complexData);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        } finally {
            mRemoteCallbackList.finishBroadcast();
            mLock.unlock();
        }
    }

(4)解绑服务

    override fun onDestroy() {
        super.onDestroy()
        mBinder?.unregisterListener(listener)
        unbindService(mConnection)
    }

看一下效果:

代码已上传gitHub

github

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1024589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux 文件锁

建议锁,强制锁,记录锁的概念 建议锁&#xff1a; 如果某一个进程对一个文件持有一把锁之后&#xff0c;其他进程仍然可以直接对文件进行操作(open, read, write)而不会被系统禁止&#xff0c;即使这个进程没有持有锁。只是一种编程上的约定。建议锁只对遵守建议锁准则的进程生…

@JsonFormat、@JSONField、@DateTimeFormat详细解说

JsonFormat、JSONField、DateTimeFormat详细解说_jsonfield format_xinlianluohan的博客-CSDN博客 三者出处 1、JsonFormat来源于jackson&#xff0c;Jackson是一个简单基于Java应用库&#xff0c;Jackson可以轻松的将Java对象转换成json对象和xml文档&#xff0c;同样也可以…

CSS SASS calc() 计算表达式或使用变量

calc&#xff08;&#xff09;是css的一个函数&#xff0c;可用于元素计算长度&#xff0c;比如div宽度想要减去一个固定宽度后并自适应&#xff0c;可以写为calc(100% - 60px) 注意“-”两边有空格 sass已经是常用的预编译语言&#xff0c;允许使用变量等规则&#xff0c;如果…

上海亚商投顾:沪指窄幅震荡微跌 两市成交金额创年内新低

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日窄幅震荡&#xff0c;创业板指盘中跌超1%&#xff0c;黄白二线有所分化。华为星闪概念股午后拉升&…

EPC与5GC/5GS互联互通

一、5GS与EPC/E-UTRAN互通的非漫游架构 1&#xff0e;N26接口是MME和5GS AMF之间的CN间接口&#xff0c;以实现EPC和NG核心之间的互通。网络中支持N26接口是可选的&#xff0c;用于互通。N26支持在S10上支持的功能的子集&#xff08;对于互通是必要的&#xff09;。 2&#xf…

面试题:HTTPS 是如何保证传输安全的?又被问了!

文章目录 1. HTTP 协议1.1 HTTP 协议介绍1.2 HTTP 中间人攻击1.3 防止中间人攻击 2. HTTPS 协议2.1 HTTPS 简介2.2 CA 认证体系 总结 1. HTTP 协议 在谈论 HTTPS 协议之前&#xff0c;先来回顾一下 HTTP 协议的概念。 1.1 HTTP 协议介绍 HTTP 协议是一种基于文本的传输协议&…

Android13 大屏设备底部显示TaskBar并NavagatonBar居右

Android 13大屏设备时底下显示任务栏以及虚拟按键靠右的问题&#xff0c; 当前需求是去掉底部任务栏的显示&#xff0c;并把虚拟按键导航栏居中显示。 修改前的效果&#xff1a; 修改后的效果&#xff1a; 通过查看源码逻辑&#xff0c;可以发现只需把isTablet相关的逻辑和…

Mybatis 映射器中映射方法接受多个参数(@Param)

前面我们介绍了使用Mybatis映射器进行数据的增删改查操作&#xff1b;本篇我们继续介绍在Mybatis映射器的映射方法中如何使用多个参数。 如果您对Mybatis使用映射器进行数据的增删改查操作不太了解&#xff0c;建议您先进行了解后再阅读本篇&#xff0c;可以参考&#xff1a; …

【数据结构】二叉树的构建与基本操作实现

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.前序建立二叉树 2.销毁二叉树 3.统计 …

uni-app 之 picker选择器

uni-app 之 picker选择器 同步滚动&#xff1a;开 uni-app 之 picker选择器 一、普通选择器 二、多列选择器 三、时间选择器 四、日期选择器 一、普通选择器 <template><view><picker change"bindPickerChange" :value"index" :range&q…

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理 在过去十年中&#xff0c;航天器一直是现代技术进步的先决条件。迄今为止&#xff0c;为了更好地完成各种实际任务&#xff0c;已经在航天器姿态控制领域进行了大量研究。航天器一旦进入太空&#xff0c;就容易出现不确定…

JavaWeb开发-05-SpringBootWeb请求响应

一.请求 1.Postman 2.简单参数 ​ package com.wjh.controller;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;/** 测试请求参数接受*/ R…

【IntelliJ IDEA】cmd和idea Terminal查看java版本不一致

问题描述 原来win10电脑上安装的是jdk8的版本&#xff0c;因某些原因&#xff0c;现在想换成jdk7的版本&#xff0c;修改环境变量后&#xff0c;在cmd中执行 [java -version]命令&#xff0c;显示的是7的版本。 但在idea的Terminal中执行&#xff0c;确实显示8的版本。 原因分…

vue设置路由模式为history,打包部署,并解决404问题

现在Router配置里面加上 base 和 mode 属性&#xff1a; export default new Router({base: /your_project_name/,mode: history,routes: [......] })这样就能支持 history 模式了&#xff0c;但是现在静态资源获取还有问题。 解决静态资源获取问题 在 config/index.js 文件…

TS中的数据类型

一、number类型 let c: number; c 10; c "hello"; // 不能复制string类型 二、string类型 let d: string; d "hello"; d 10; // 不能复制number类型 三、boolean类型 let e: boolean true; e false; e 10; // 不能赋值true和false以外的值 四…

Cypress安装与使用教程(1)—— 软测大玩家

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

半导体划片机工艺应用

半导体划片工艺是半导体制造过程中的重要步骤之一&#xff0c;主要用于将大尺寸的晶圆切割成小片&#xff0c;以便进行后续的制造和封装过程。以下是一些半导体划片工艺的应用&#xff1a; 晶圆划片&#xff1a;在半导体制造过程中&#xff0c;需要将大尺寸的晶圆切割成小片&am…

【数据库系统概论】数据库系统外部的体系结构

单用户结构主从式结构分布式结构客户机&#xff0f;服务器结构&#xff08;C/S结构&#xff09;浏览器 / 服务器结构&#xff08;B/S结构&#xff09;感谢 &#x1f496; 上一篇文章 数据库系统的三级模式和二级映射介绍的是数据库系统内部的体系结构&#xff0c;是从应用开发…

计算机网络知识补充(1)

计算机网络:是一个将分散的&#xff0c;具有独立功能的计算机系统&#xff0c;通过通信设备和线路进行连接起来&#xff0c;由功能完善的软件实现资源共享和信息共享的系统&#xff0c;计算机网络是互连的&#xff0c;自治的计算机集合 互连:通过通信链路来进行互联互通 自治:没…

云安全威胁和责任

云计算的共享特性和按需定制本质除了给企业带来效率上提升&#xff0c;也引入了新的安全威胁&#xff0c;有可能使企业得不偿失。 之前云安全联盟(CSA)的报告便指出&#xff0c;云服务天生就能使用户绕过公司范围内的安全策略&#xff0c;建立起自己的影子IT项目服务账户。 新的…