Android - AIDL

一、概念

Android接口定义语言(Android Interface Definition Language),可用来定义客户端与服务均认可的编程接口,以便二者进程间通信。只有当你允许来自不同的客户端访问你的服务并且需要处理多线程问题时才必须使用AIDL,否则使用其它IPC方法。

IBinder是一个接口,代表了一种跨进程通信的能力。只要实现了这个借口,这个对象就能跨进程传输。
IInterface是一个接口,代表的就是 Server 进程对象具备什么样的能力(能提供哪些方法,其实对应的就是 AIDL 文件中定义的接口)
Binder

Java 层的 Binder 类,代表的其实就是 Binder 本地对象。BinderProxy 类是 Binder 类的一个内部类,它代表远程进程的 Binder 对象的本地代理;这两个类都继承自 IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder 驱动会自动完成这两个对象的转换。

Stub

是一个抽象类,AIDL 的时候编译器 会给我们生成一个名为 Stub 的静态内部类;这个类继承了 Binder, 说明它是一个 Binder 本地对象,它实现了 IInterface 接口,表明它具有 Server 承诺给 Client 的能力;Stub 是一个抽象类,具体的 IInterface 的相关实现需要开发者自己实现。

二、Server 端

2.1 定义接口

定义接口声明功能,手动创建的是 .aidl 文件,调用 IDE 的 rebuild 生成 .java 文件。

2.1 定义 .aidl 接口文件

  1. Module右键→New→AIDL→AIDL File(如果不可选,在 module 的 build.gradle 的 <android> 节点下的 <buildFeatures> 节点中添加 aidl true)。
  2. 在创建的接口中声明抽象方法(IDE生成的默认方法可以删掉,只能用 Java 语法写)。

2.2 生成 .java 接口文件

IDE 点击 Rebuild Project 就会生成对应的 .java 文件,每次修改了 .aidl 文件都需要 Rebuild 一下。(Android视图目录在 java(generated) 里,Program视图目录在 build/generated/aidl_source_output_dir 里)。

2.2 提供服务

创建一个 Service 来对外提供服务。

  1. 创建一个 Service,内部实现在 .java 接口文件中生成的 Stub,重写之前定义的那些抽象方法。在 onBind() 中返回这个接口实例供 Client 端获取调用。
  2. 在 AndroidManifest.xml 中对 Service 进行注册,配置 <process> 为单独的进程、<exported> 为 true 供外部访问、<intent-filter> 用于隐式跳转 、<permission>  外部声明该权限才能访问。
class DemoService : Service() {
    //也可以用 by lazy + object 写成属性然后在 onBind() 中返回
    override fun onBind(intent: Intent?): IBinder {
        return DemoAidlImpl()
    }
    private inner class DemoAidlImpl : IDemoAidlInterface.Stub() {
        private var content = ""
        override fun getContent(): String {
            return content
        }
        override fun setContent(str: String) {
            content = str
        }
    }
}
<service
    android:name=".test.DemoService"
    android:exported="true"
    android:process="aidl"
    android:permission="com.example.demo.aidlService"
    >
    <intent-filter>
        <action android:name="com.example.demo.aidlService"/>
    </intent-filter>
</service>

三、Client 端

如果客户端和服务端不在同一应用内(几乎都是),则客户端内也要有接口文件的副本。

3.1 接口访问

Moudle右键→New→Filder→Aidl Folder 新建文件夹,然后创建一个和 Server 端名称相同的包(不能创建 package 就同样是在 module 的 build.gradle 的 <android> 节点下的 <buildFeatures> 节点中添加 aidl true),将 Server 端的 .aidl 文件复制粘贴过去,最后Rebuild一下。

3.2 开启服务

class AidlActivity : Activity() {
    val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            //拿到对象就可以调用各种方法了
            val binder = IDemoAidlInterface.Stub.asInterface(service)
        }
        override fun onServiceDisconnected(name: ComponentName?) {}
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //开启服务
        Intent().apply {
            `package` = "com.jomurphys.demo"    //服务端的包名
            action = "com.jomurphys.demo.aidlService"   //服务端Service配置的intent-filter中的action
            bindService(this, connection, BIND_AUTO_CREATE)
        }
    }
}
  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值