Android 进程间通信——AIDL学习与使用

一、概述

AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。目的是为了实现进程间通信,尤其是在涉及多进程并发情况下的进程间通信。
AIDL的语法和Java是一样的,只是在一些细微处有些许差别:

  • 文件类型:用AIDL书写的文件的后缀是 .aidl,而不是 .java。

  • 数据类型:AIDL默认支持一些数据类型,在使用这些数据类型的时候是不需要导包的,但是除了这些类型之外的数据类型,在使用之前必须导包。默认支持的数据类型包括:Java中的八种基本数据类型,包括 byte,short,int,long,float,double,boolean,char。String 类型。CharSequence类型。
    List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。List可以使用泛型。
    Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。Map是不支持泛型的。

  • 定向tag:AIDL中的定向 tag 表示了在跨进程通信中数据的流向,其中 in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。另外,Java 中的基本类型和 String ,CharSequence 的定向 tag 默认且只能是 in 。注意:不要滥用定向 tag ,而是要根据需要选取合适的,全都用 inout ,等工程大了系统的开销就会大很多。

  • 两种AIDL文件:AIDL文件大致可以分为两类。一类是用来定义parcelable对象,以供其他AIDL文件使用AIDL中非默认支持的数据类型的。一类是用来定义方法接口,以供系统使用来完成跨进程通信的。

二、简单使用

2.1 服务端实现

数据类
首先要定义两个进程间通信的数据类,由于不同的进程有着不同的内存区域,并且它们只能访问自己的那一块内存区域。所以我们必须将要传输的数据转化为能够在内存之间流通的形式。这个转化的过程就叫做序列化与反序列化。选择的序列化方式是实现 Parcelable 接口。

@Parcelize
data class Book(var name: String? = null, var price: Int = 0) : Parcelable {
   
    fun readFromParcel(dest: Parcel) {
   
        //注意,此处的读值顺序应当是和writeToParcel()方法中一致的
        name = dest.readString()
        price = dest.readInt()
    }
}

在kotlin中,中实现 Parcelable 非常简单首先,在所属模块的 build.gradle 文件中应用 kotlin-parcelize 插件,然后在定义的实体类添加 @Parcelize 注解,并实现 Parcelable 接口即可。注意:添加 @Parcelize 注解生成器就会自动创建writeToParcel()/ createFromParcel()方法,但不会生成readFromParcel()方法,而如果要支持为 out 或者 inout 的定向 tag 的话,还需要实现 readFromParcel() 方法

plugins {
   
    id 'com.android.application'
    id 'kotlin-android'
    /*序列化插件*/
    id 'kotlin-parcelize'
}

书写AIDL文件
鼠标移到app上面去,点击右键,然后 new->AIDL->AIDL File
在这里插入图片描述

Book.aidl

// Book.aidl
package com.matt.myaidltest.ipc;

//注意parcelable是小写
parcelable Book;

BookManager.aidl

// BookManager.aidl
package com.matt.myaidltest.ipc;
import com.matt.myaidltest.ipc.Book;

interface BookManager {
   
    //所有的返回值前都不需要加任何东西,不管是什么数据类型
    List<Book> getBooks();

    //传参时除了Java基本类型以及String,CharSequence之外的类型
    //都需要在前面加上定向tag,具体加什么量需而定
    void addBook(in Book book);
}

注意:Book.kt 的包名要与 Book.aidl 一致,不然会会报 Symbol not found 的错误
在这里插入图片描述
如果包名路径不一致的话,修改 build.gradle 文件:在 android{} 中间加上下面的内容:

sourceSets {
   
    main {
   
        java.srcDirs = ['src/main/java', 'src/main/aidl']
    }
}

在写完AIDL文件后,需要Rebuild Project一下项目,生成相应文件,然后再编写Server

编写服务端代码

/**
 * 服务端的AIDLService
 *
 */
class AIDLService : Service() {
   
    val TAG = this.javaClass.simpleName

    //包含Book对象的list
    private var list: MutableList<Book> = mutableListOf()

    //由AIDL文件生成的BookManager
    private val mBookManager: BookManager.Stub = object : BookManager.Stub
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值