Kotlin进程通信------AIDL

前篇介绍了进程通信中,串行通信的方式Messenger。但如果进程间,有多个方法要并行调用,那么Messenger就不合适使用,而应该使用AIDL方式。

Java方式的AIDL,在之前的文章中有介绍:Android远程接口之AIDL——Parcelable、in、out、inout简例

此处,主要将前文中的Java方式用Kotlin方式翻译。

AIDL方式通信,在Kotlin中遵循和Java中同样的规则,包括数据结构的限制,AIDL文件的编写。

一、AIDL文件编写

AIDL文件的编写,有特定的要求如下:

支持数据类型如下:
1. Java 的原生类型
2. String 和CharSequence
3. List 和 Map ,List和Map 对象的元素必须是AIDL支持的数据类型;  以上三种类型都不需要导入(import)
4. AIDL 自定义生成的接口  需要导入(import)
————————————————
版权声明:本文为CSDN博主「战国剑」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yangzhaomuma/article/details/50576017

除基础类型外,如果我们要自定义类,需要手动导入(import),并且aidl文件和同名类文件的位置,有做要求:

以上图为例:

1、aidl文件夹与java文件夹,同层次

2、自定义的类,如果要在aidl中使用,有两个需要注意的地方:

      2-1: 需要在java文件夹、aidl文件夹两处地方都做定义,并且包名需要一致,如图中的UserInfo类。

     2-2: 如UserInfo这种在aidl中使用的自定义类,需要实现 Parcelable 接口。

了解以上规则,就用代码实现相应逻辑。

3、具体的AIDL文件如下(kotlin中,具体的aidl文件写法,还是java形式的):

3-1 IBase.aidl

// IBase.aidl
package com.me.kotlinprocess;
import com.me.kotlinprocess.aidl.UserInfo;
// Declare any non-default types here with import statements

interface IBase {
   int add(int i,int j);
   String getUserInfo(in UserInfo userInfo);
   void getaList(out String[] list);
   void setaList(in String[] list);
   void gettList(inout String[] list);
}

3-2 UserInfo.aidl

// UserInfo.aidl
package com.me.kotlinprocess.aidl;

// Declare any non-default types here with import statements
parcelable UserInfo;

二、server端实现

server端,只需要实现service接口,并返回onBind的实现即可。此处IBase.Stub即是服务的实现。

kotlin中,服务的实现,应该是屏蔽了in、out 、inout参数的差异。此处生成的方法都是统一以out修饰。此处有疑议,如有不对请指出。

class AidlService : Service() {

    override fun onBind(intent: Intent?): IBinder? {
        return stub
    }

    val stub:IBase.Stub = object:IBase.Stub(){
        override fun add(i: Int, j: Int): Int {
            return i+j
        }

        override fun getUserInfo(userInfo: UserInfo?): String {
            val resultString : String = "---- ${userInfo?.name}  ${userInfo?.address} ${userInfo?.age} ----"
            return resultString
        }

        override fun getaList(list: Array<out String>?) {
            println("getaList ${list?.get(0)}")
        }

        override fun setaList(list: Array<out String>?) {
            println("setaList ${list?.get(0)}")
        }

        override fun gettList(list: Array<out String>?) {
            println("gettList ${list?.get(0)}")
        }


    }
}

三、client端实现

client端的实现,流程也很清晰。先连接上服务,之后,可通过接口调用具体的服务。

1、连接服务

var iBase: IBase? = null
//连接定义
private val serviceConnect = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            println("connect success")
            iBase = IBase.Stub.asInterface(service)
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            println("connect fail")
            iBase = null
        }
    }


//连接服务
bindService(
                Intent(this, AidlService::class.java),
                serviceConnect,
                Context.BIND_AUTO_CREATE
            )

2、调用服务

fun testAidl() {
        val add = iBase?.add(1, 2)
        println("add result $add")
        val userInfo: UserInfo = UserInfo()
        userInfo.name = "bob"
        userInfo.address = "hangzhou"
        userInfo.age = 20
        val userInfo1 = iBase?.getUserInfo(userInfo)
        println("userInfo result $userInfo1")
    }

最后,别忘了在manifest中加上service的定义:

<service
            android:name=".aidl.AidlService"
            android:label="@string/aidl_name"
            android:process=":aidl_remote">
        </service>

至此,完成aidl的进程通信。

aidl的信息通信,主要的嘈点在于aidl文件编写和规范、连接管理较为繁琐。可以在这基础上,封装一套简易通信框架。期待后续。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值