Kotlin--›IPC跨进程通信之AIDL(双向通信)

上一篇文章介绍了 IPC跨进程通信之Messager(双向通信)

Messenger是系统对aidl一个轻量封装, 方便使用, 但是有一定局限性.

本文介绍直接介绍aidl的使用, 让跨进程通信就跟本地调用一样爽.


准备

  1. 定义调用接口
  2. 创建相应的自定义数据Bean

这里写图片描述
用系统自带的菜单, 创建AIDL文件, 并写上自己的接口定义.
你也可以直接创建File后缀名为aidl,没毛病;

这里写图片描述

需要注意的点
自定义的数据类型, 需要手动import xxx.xxx, 系统不会自动导入.
参数类型还可以使用in out inout标识.

这里写图片描述

需要注意的点
自定义的数据类, 需要在aidl文件夹中, 创建对应的aidl文件, 并且包名类名需要完全一致.


服务端编写

class RemoteService : Service() {

    /*用来和客户端通信的回调*/
    var callback: ICallback? = null

    private fun sendText(what: Int, text: String) {
        callback?.callback("服务端回调:", MsgBean(text))
    }

    val myAidlInterface = object : IMyAidlInterface.Stub() {
        override fun addCallback(callback: ICallback?) {
            [email protected] = callback
        }

        override fun sendMsg(msg: MsgBean?): Int {
            sendText(200, msg?.message ?: "empty")
            return 200
        }

        override fun getMsg(flag: Int): MsgBean {
            return MsgBean("getMsg 测试_flag:$flag")
        }
    }

    override fun onBind(p0: Intent?): IBinder {
        return myAidlInterface //直接返回成员对象
    }
}

相较于Messenger方式, 服务端的代码简洁了很多.

客户端编写

class MainActivity : AppCompatActivity() {

    //声明对象
    var myAidlInterface: IMyAidlInterface? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val remoteServiceIntent = Intent(this, RemoteService::class.java)
        val remoteCon = object : ServiceConnection {
            override fun onServiceDisconnected(p0: ComponentName?) {
                L.e("call: onServiceDisconnected -> $p0")

                showText("onServiceDisconnected_${p0}")

                myAidlInterface = null
            }

            override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
                L.e("call: onServiceConnected -> $p0 $p1")
                showText("onServiceConnected_${p0}")

                //需要通过asInterface的方式,创建对象
                myAidlInterface = IMyAidlInterface.Stub.asInterface(p1)
                sendText(1, "客户端连接成功...")
            }
        }

        findViewById<View>(R.id.bind).setOnClickListener {
            bindService(remoteServiceIntent, remoteCon, Service.BIND_AUTO_CREATE)
        }
    }

    private fun sendText(what: Int, text: String) {
        myAidlInterface?.let {
            //直接调用对象的方法进行通信,即可.
            it.addCallback(object : ICallback.Stub() {
                override fun callback(str: String?, msg: MsgBean?) {
                    showText("callback 回调:$str $msg")
                }
            })

            val sendMsg = it.sendMsg(MsgBean("${what}_${text}"))
            L.e("call: sendText -> 返回值:$sendMsg  ${it.getMsg(404)}")
        }
    }
}

不要忘了在AndroidManifest.xml声明:

<service
  android:name=".RemoteService"
  android:process=":remote"/>

源码地址: https://github.com/angcyo/IPC_AIDL

也许你还想学习更多, 来我的群吧, 我写代码的能力, 远大于写文章的能力:

联系作者

点此快速加群

请使用QQ扫码加群, 小伙伴们都在等着你哦!

关注我的公众号, 每天都能一起玩耍哦!

猜你喜欢

转载自blog.csdn.net/angcyo/article/details/81301882
今日推荐