当前位置: 首页 > news >正文

android进阶-AIDL

参考:Android进阶——AIDL详解_android aidl-CSDN博客

AIDL(Android 接口定义语言),可以使用它定义客户端与服务端进程间通信(IPC)的编程接口,在 Android 中,进程之间无法共享内存(用户空间),不同进程之间的通信一般使用 AIDL 来处理。

使用流程:

在 .aidl 文件中定义 AIDL 接口,并将其添加到应用工程的 src 目录下,创建完成之后 rebuil
Android SDK 工具会自动生成基于该 .aidl 文件的 IBinder 接口,具体的业务对象实现这个接口,这个具体的业务对象也是 IBinder 对象,当绑定服务的时候会根据实际情况返回具体的通信对象(本地还是代理)
将客户端绑定到该服务上,之后就可以调用 IBinder 中的方法来进行进程间通信(IPC)实际起作用的并不是AIDL文件,而是据此而生成的一个IInterface的实例代码,AIDL其实是为了避免我们重复编写代码而出现的一个模板

在实现AIDL的过程中服务端APP和客户端APP中要包含结构完全相同的AIDL接口文件,包括AIDL接口所在的包名及包路径要完全一样,否则就会报错,这是因为客户端需要反序列化服务端中所有和AIDL相关的类,如果类的完整路径不一致就无法反序列化成功。

小技巧:为了更加方便的创建AIDL文件,我们可以新建一个lib工程,让客户端APP和服务端APP同时依赖这个lib,这样只需要在这个lib工程中添加AIDL文件就可以了!

如果不需要跨不同程序,使用Binder来创建接口,如果不需要处理多线程,使用Messenger来处理,使用AIDL务必理解绑定服务。

抽象类stub,其继承了android.os.Binder、实现IaidlData接口故,我们实际需要实现的是Stub抽象类。

package com.yqw.servicedemo;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
 
import com.yqw.mylibrary.IMyAidlInterface;
 
public class MyService extends Service {
    public static final String TAG = "MyService";
    public MyService() {
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // Return the communication channel to the service.
        return binder;
    }
 
    private IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
        @Override
        public int borrowBook(String bookName) throws RemoteException {
            //TODO 实现一系列 借书 的逻辑后,返回结果码,比如:0为失败,1为成功
            return 1;
        }
 
        @Override
        public int returnBook(String bookName) throws RemoteException {
            //TODO 实现一系列 还书 的逻辑后,返回结果码,比如:0为失败,1为成功
            return 1;
        }
    };
}
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/you943047219/article/details/109493490

package com.yqw.aidldemo;
 
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
 
import com.yqw.mylibrary.IMyAidlInterface;
 
import androidx.appcompat.app.AppCompatActivity;
 
public class MainActivity extends AppCompatActivity {
    private String TAG = "MainActivity>>";
    private IMyAidlInterface iMyAidlInterface;
    private boolean isConnected = false;//是否连接服务
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    @Override
    protected void onStart() {
        super.onStart();
        if (!isConnected) {
            mBindService();
        }
    }
 
    @Override
    protected void onStop() {
        super.onStop();
        if (isConnected) {
            unbindService(mServiceConnection);
            isConnected = false;
        }
    }
 
    private void mBindService() {
        Intent intent = new Intent();
        intent.setAction("com.yqw.servicedemo.MyService");
        intent.setPackage("com.yqw.servicedemo");
 
        bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
    }
 
    private final ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.d(TAG, "onServiceConnected");
            //获得 aidl定义的接口持有类
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
            isConnected = true;
        }
 
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG, "onServiceDisconnected");
            isConnected = false;
        }
    };
 
    private void showToast(String str) {
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    }
 
    public void borrowBook(View view) {
        if (!isConnected) {
            showToast("未连接服务");
            return;
        }
        try {
            int resultCode = iMyAidlInterface.borrowBook("流浪地球");
            showToast(resultCode == 1 ? "借书成功" : "借书失败");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
 
    public void returnBook(View view) {
        if (!isConnected) {
            showToast("未连接服务");
            return;
        }
        try {
            int resultCode = iMyAidlInterface.returnBook("流浪地球");
            showToast(resultCode == 1 ? "还书成功" : "还书失败");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

AIDL支持实体类,但必须是实现了Parcelable接口,支持序列化。

  1. // Book.aidl

  2. package com.yqw.mylibrary;

  3. parcelable Book;

package com.yqw.mylibrary;
 
public class Book {
    String name;
    int num;
 
    public Book(String name, int num) {
        this.name = name;
        this.num = num;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getNum() {
        return num;
    }
 
    public void setNum(int num) {
        this.num = num;
    }
}

然后实现 Parcelable接口,按Alt+Enter自动补充好需要的代码

package com.yqw.mylibrary;
 
import android.os.Parcel;
import android.os.Parcelable;
 
public class Book implements Parcelable {
    String name;
    int num;
 
    public Book(String name, int num) {
        this.name = name;
        this.num = num;
    }
 
    protected Book(Parcel in) {
        name = in.readString();
        num = in.readInt();
    }
 
    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }
 
        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getNum() {
        return num;
    }
 
    public void setNum(int num) {
        this.num = num;
    }
 
    @Override
    public int describeContents() {
        return 0;
    }
 
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(num);
    }
}

// IMyAidlInterface.aidl
package com.yqw.mylibrary;
import com.yqw.mylibrary.Book;
 
interface IMyAidlInterface {
 
    int borrowBook(String bookName);
    int returnBook(String bookName);
 
    List<Book> getBookList();
 
}

然后调用:

    public void getBooksNum(View view) {
        checkConnected();
        try {
            int booksNum = iMyAidlInterface.getBookList().size();
            showToast("剩余图书数量:" + booksNum);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

相关文章:

android进阶-AIDL

参考&#xff1a;Android进阶——AIDL详解_android aidl-CSDN博客 AIDL&#xff08;Android 接口定义语言&#xff09;&#xff0c;可以使用它定义客户端与服务端进程间通信&#xff08;IPC&#xff09;的编程接口&#xff0c;在 Android 中&#xff0c;进程之间无法共享内存&…...

贪心算法-活动选择问题背包问题

目录 活动选择问题 无重叠区间-Leetcode 435 分数背包问题--贪心解法 贪心法 0-1 背包问题 贪心法 贪心算法的局限 Set cover problem 活动选择问题 分析: /* 要在一个会议室举办n个活动 - 每个活动有它们各自的起始和结束时间 - 找出在时间上互不冲突的活动组合,能…...

Web3工具集合 - 00

使用 React 和 Material-UI 构建的 Web3 工具集合 大家好&#xff01; 我很高兴向大家介绍我最近刚启动了一个项目&#xff1a;Web3 工具集合。 这个项目的目的是一个集成各种 Web3 工具的网站&#xff0c;旨在为开发人员和加密货币爱好者提供便捷的工具和资源。 特点&#…...

分布式与集群的区别

先说区别&#xff1a; 分布式是并联工作的&#xff0c;集群是串联工作的。 分布式中的每一个节点都可以做集群。而集群并不一定就是分布式的。 集群举例&#xff1a;比如新浪网&#xff0c;访问的人很多&#xff0c;他可以做一个集群&#xff0c;前面放一个相应的服务器&…...

学习心得:如何开始学习一款MCU

一、MCU简介 任何一款MCU&#xff0c;其基本原理和功能都是大同小异&#xff0c;所不同的只是其外围功能模块的配置及数量、指令系统等。对于指令系统&#xff0c;虽然形式上看似千差万别&#xff0c;但实际上只是符号的不同&#xff0c;其所代表的含义、所要完成的功能和寻址…...

顺序表的实现(迈入数据结构的大门)(1)

上一节我们认识到了什么是数据结构 这一节我们就来实现第一个数据结构的实现 思考一个问题&#xff1a; 假定一个数组&#xff0c;空间为10&#xff0c;已经使用了5个&#xff0c;向其中插入数据的步骤&#xff1a; 1.插入数据&#xff0c;我们先要求数组长度&#xff0c;其…...

RERCS系统-WDA+BOPF框架实战例子 PART 1-新建List UIBB(列表组件)并分配Feeder Class和Node Element

需求背景&#xff1a; 已有的项目主数据功能&#xff0c;新增一个列表UIBB显示主数据额外的关联数据明细。 1、Fiori页面通过右键-技术帮助打开对应的组件配置&#xff1b; 2、双击对应的组件配置&#xff0c;调整对应的页面新建UIBB&#xff1b; 3、填写对应的UIBB属性字段&a…...

如何从 iPhone 恢复已删除或丢失的联系人?

不小心删除了您的 iPhone 联系人&#xff1f;不用担心。我们将向您展示如何从 iPhone或 iPad恢复已删除或丢失的联系人。当您从 iPhone 中删除联系人时&#xff0c;您可能认为无法将其恢复。但事实是&#xff0c;您可以从 iPhone 或 iPad 恢复已删除的联系人&#xff0c;因为它…...

RISCV 外部GCC 工具链安装@FreeBSD15

在交叉编译的时候&#xff0c;可以使用FreeBSD15默认的工具链&#xff1a;LLVM 也可以使用GCC工具链&#xff0c;GCC可以使用现成pkg包安装&#xff0c;也可以编译安装。 LLVM的特点是高移植性和高效&#xff0c;但学习成本高。GCC的特点是成熟稳定&#xff0c;但优化能力有限…...

全栈开发之路——前端篇(9)插槽、常用api和全局api

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇&#xff1a;setup语法&#xff0c;设置响应式数据。 第四篇&#xff1a;数据绑定、计算属性和watch监视 第五篇 : 组件…...

减瘦误区、雷点、陷阱和挑战怎么应对

在减瘦过程中&#xff0c;很多肥胖人群都容易踩到坑。比如陷入误区&#xff0c;认为只有短期快速的减调方式方法&#xff0c;才值得尝试&#xff0c;而忽视身体健康&#xff1b;或是踩到雷点&#xff0c;轻信强速方剂或方法&#xff0c;结果身体产生了排斥或根本没效用白花钱&a…...

Leetcode—946. 验证栈序列【中等】

2024每日刷题&#xff08;133&#xff09; Leetcode—946. 验证栈序列 实现代码 class Solution { public:bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {int left 0;for(int i 0; i < popped.size(); i) {while(left &…...

Selenium定位方法及代码

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

GitHub搭建免费博客

一、GitHub仓库准备 ​ 搭建博客需要准备两个仓库。一个存放博客图床的仓库&#xff0c;另一个存放博客网站的仓库。 1.1、图床创建 新建仓库 第一步&#xff1a; ​ 第二步&#xff1a; 生成Token令牌 点击右上角头像->Settings->下拉&#xff0c;直到左侧到底&#…...

开源代码分享(28)-含分布式光伏的配电网集群划分和集群电压协调控制

参考文献&#xff1a; [1] Chai Y , Guo L , Wang C ,et al.Network Partition and Voltage Coordination Control for Distribution Networks With High Penetration of Distributed PV Units[J].IEEE Transactions on Power Systems, 2018:3396-3407.DOI:10.1109/TPWRS.2018…...

idea-自我快捷键-2

1. 书签 创建书签&#xff1a; 创建书签&#xff1a;F11创建特色标记书签&#xff1a;Ctrl F11快速添加助记符书签&#xff1a;ctrl shift 数字键 查看书签&#xff1a; shift F11快速定位到助记符书签&#xff1a;Ctrl 数字键 删除书签&#xff1a; delete 2. 自动…...

深入学习指针3

目录 前言 1.二级指针 2.指针数组 3.指针数组模拟二维数组 前言 Hello,小伙伴们我又来了&#xff0c;上期我们讲到了数组名的理解&#xff0c;指针与数组的关系等知识&#xff0c;那今天我们就继续深入到学习指针域数组的练联系&#xff0c;如果喜欢作者菌生产的内容还望不…...

礼赞劳动节,致敬劳动者。节日随想:疾笔耕耘也是一种劳动方式。

马克思也快诞辰了206年了&#xff0c;恩格斯领导的第二国际通过的决议节日也迎来了134岁的生日了&#xff0c;我也继续在劳动的路上。 五月是值得纪念的日子&#xff0c;作为一名无上光荣的分子&#xff0c;无比仰慕崇拜的两位先驱前辈大胡子&#xff0c;其一 生于斯&#xff0…...

学习Java的日子 Day45 HTML常用的标签

Day45 HTML 1.掌握常用的标签 1.1 标题标签 h1-h6 <h1>一级标签</h1> <h2>二级标签</h2> <h3>三级标签</h3> <h4>四级标签</h4> <h5>五级标签</h5> <h6>六级标签</h6> 显示特点&#xff1a; * 文字…...

兔子与狮子

兔子与狮子 一只骨瘦如柴的兔子&#xff0c;在慢悠悠地吃草 趴在边上的狮子说&#xff0c;多吃点吧&#xff0c;你身上一点肉都没有 兔子说&#xff0c;我正在减肥&#xff0c;体重越来越轻&#xff0c;骨头越来越硬 狮子舔了舔嘴巴&#xff0c;你再狡猾&#xff0c;也是我的…...

GNU/Linux - 系统启动流程及rcS脚本介绍

Linux系统启动流程 在 Linux 系统启动过程中&#xff0c;会按特定顺序执行多个脚本和初始化例程&#xff0c;以使系统进入可用状态。虽然具体顺序可能因 Linux 发行版和版本而异&#xff0c;但以下是典型执行顺序的概括性概述&#xff1a; 1. BIOS/UEFI&#xff1a; 系统开机后…...

对象,字符串的解构赋值

大家想了解更多&#xff0c;可以去看阮一峰的ECMAScript6(ES6)标准入门课程 对象 简介 解构不仅可以用于数组&#xff0c;还可以用于对象。 let { foo, bar } { foo: aaa, bar: bbb }; foo // "aaa" bar // "bbb" 对象的解构与数组有一个重要的不同。…...

Django 静态文件管理与部署指南

title: Django 静态文件管理与部署指南 date: 2024/5/10 17:38:36 updated: 2024/5/10 17:38:36 categories: 后端开发 tags: WebOptCDN加速DjangoCompressWebpackStaticDeployCICD-ToolsSecStatic 第一章&#xff1a;介绍 Django 静态文件的概念和重要性 在 Web 开发中&a…...

ORACLE ODAX9-2的一个误告警Affects: /SYS/MB的分析处理

在运维的多套ORACLE ODAX9-2版本&#xff0c;都遇到了一个计算节点的告警&#xff1a;Description: The service Processor poweron selftest has deteced a problem. Probabity;:100, UulD:cd1ebbdf-f099-61de-ca44-ef646defe034, Resource:/SYS/MB,&#xff1b;此告警从描述上…...

Spring AOP浅谈

什么是AOP&#xff1f; AOP是Aspect-Oriented Programming的缩写&#xff0c;是一种面向切面的编程方法。 在AOP中&#xff0c;一个切面是一组可以独立于其他代码执行的功能&#xff0c;如日志记录、安全性检查、事务处理等。这些功能通常被称为"通知"&#xff0c;并…...

数据结构——图的基础知识与其表示

一&#xff1a;图的定义 由顶点的集合和边的集合组成&#xff1b;常以 G(V,E) 表示&#xff0c;G 代表图&#xff0c;V代表 顶点的集合&#xff0c;E代表边的集合&#xff1b; 如图&#xff1a; 在G1图中&#xff0c;有 0~4 五个顶点&#xff0c;有 0-1&#xff0c;0-2&…...

数据库管理-第187期 23ai:怎么用SQL创建图(20240510)

数据库管理187期 2024-05-10 数据库管理-第187期 23ai:怎么用SQL创建图&#xff08;20240510&#xff09;1 安装PGX1.1 数据库配置对应用户1.2 使用RPM包安装Graph Server1.3 安装Oracle Graph Client1.4 访问PGX页面 2 SQL Property Graph2.1 创建SQL属性图2.2 关于点和边图元…...

基于VOLOPV2的自动驾驶环境感知系统

基于VOLOPV2的自动驾驶环境感知系统是一个复杂的系统&#xff0c;它主要负责实时检测并识别周围环境中的各种物体和信息&#xff0c;为自动驾驶车辆提供必要的感知数据。以下是对该系统的一个简要介绍&#xff1a; 环境感知是自动驾驶系统中的一个关键部分&#xff0c;它依赖于…...

使用Python爬虫会遇到的问题和解决方法(包含案例)

一、HTTP错误&#xff08;如403 Forbidden&#xff09; 问题描述&#xff1a; 当使用requests库发起请求时&#xff0c;可能会遇到HTTP 403 Forbidden错误&#xff0c;这通常意味着服务器理解了请求&#xff0c;但是拒绝执行它。 解决方法&#xff1a; 1.设置headers&#xf…...

Spring Boot 读取配置优先级顺序是什么?

在使用 Spring Boot 进行开发时&#xff0c;配置文件是非常重要的一部分&#xff0c;它可以用来配置应用程序的行为、数据源、日志级别等信息。 但是&#xff0c;当配置文件中存在多个配置来源时&#xff0c;Spring Boot 是如何确定读取配置的优先级顺序的呢&#xff1f; 本文…...