Android进阶之路Android开发Android开发经验谈

简单学习AIDL

2019-10-31  本文已影响0人  鲨鱼尤德曼

AIDL全称为Android Interface Definition Language(安卓接口定义语言),适用于不同应用的客户端进程通过 IPC 方式访问服务,以下例子为了方便将在一个App里定义Service为独立进程,恰巧我最近学习kotlin,所以用的是kotlin语法(不过大同小异~~)。在实现AIDL之前,要先理解绑定服务。

最终效果图


进程间通信

实现步骤

1.生成AIDL文件,成功之后会看到有AIDL文件夹

右键点击项目生成AIDL文件

生成服务端的AIDL文件 ISer


interface ISer {

/**

* Demonstrates some basic types that you can use as parameters

* and return values in AIDL.

*/

    void basicTypes(int anInt,long aLong,boolean aBoolean,float aFloat,double aDouble,String aString);

    void registerCallback(IServiceCallback cb);

    void unregisterCallback(IServiceCallback cb);

}

其中这个方法是自动生成,不用可以删除

void basicTypes(int anInt,long aLong,boolean aBoolean,float aFloat,double aDouble,String aString);

这两个方法是自定义的注册与注销回调方法,IServiceCallback也是生成的AIDL

void registerCallback(IServiceCallback cb);

void unregisterCallback(IServiceCallback cb);

IServiceCallback用于回调监听到的数字

interface IServiceCallback {
    void valueChanged(int value);
}
现在你有两个AIDL文件 同时在 java(generated) 文件夹里会生成同名的java文件, 里面的静态抽象类Stub继承自Binder,实现了AIDL接口(下面步骤会用到)。

 
2.声明一个IBinder接口实例,并且在Service的onBind()方法中返回此实例

/**
 * 服务端
 */
class RemoteService : Service() {
    var mValue = 0
    //控制IServiceCallback接口的注册和注销
    val callbackList = RemoteCallbackList<IServiceCallback>()

    //每隔一秒发送自增的值
    private val handler = Handler(Handler.Callback {
        if (it.what == Const.REPORT_MSG) {
            val value = mValue++
            val N = callbackList.beginBroadcast()
            for (i in 0 until N) try {
                callbackList.getBroadcastItem(i).valueChanged(value)//回调自增的值
            } catch (e: RemoteException) {
                e.printStackTrace()
            }
            callbackList.finishBroadcast()
            it.target.run {
                sendMessageDelayed(obtainMessage(Const.REPORT_MSG), (1 * 1000).toLong())
            }
        }
        false
    })

    override fun onCreate() {
        super.onCreate()
        Const.log("Service  onCreate")
        handler.sendEmptyMessage(Const.REPORT_MSG)// 发送信息,开始自增
    }

    override fun onBind(intent: Intent): IBinder {
        //返回IBinder实例
        return binder
    }

    //ISer.Stub继承自Binder类
    private val binder = object : ISer.Stub() {
        override fun registerCallback(cb: IServiceCallback?) {
            cb?.run { callbackList.register(this) }
        }

        override fun unregisterCallback(cb: IServiceCallback?) {
            cb?.run { callbackList.unregister(this) }
        }

        override fun basicTypes(anInt: Int, aLong: Long, aBoolean: Boolean, aFloat: Float, aDouble: Double, aString: String?) {
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        Const.log("Service  onDestroy")
        //Service消毁的时候移除 RemoteCallbackList 里面的全部回调
        callbackList.kill()
        //移除 Handler 全部回调和消息
        handler.removeCallbacksAndMessages(null)
    }
}

 
3.客户端实现ServiceConnection
客户端在onServiceConnected() 回调中收到IBinder时,必须调用 yourServiceInterface(你的接口名).Stub.asInterface(service),以将返回的参数转换成 yourServiceInterface类型

   var remoteService: ISer? = null
    private val serviceConnection = object : ServiceConnection {
        override fun onServiceDisconnected(name: ComponentName?) {
            Const.log("Service has  unexpectedly disconnected ")
            remoteService = null
        }

        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            remoteService = ISer.Stub.asInterface(service) //转换成Iser接口
            remoteService?.registerCallback(callback) //注册监听
            Const.log("  onServiceConnected::${name?.className}::: ")
        }
    }

接口回调

   val callback = object : IServiceCallback.Stub() {
        override fun valueChanged(value: Int) {
            clientHandler.run { sendMessage(obtainMessage(Const.BUMP_MSG, value, 0)) }
        }
    }

Handler更新TextView

  val clientHandler = Handler(Handler.Callback {
        when (it.what) {
            Const.BUMP_MSG -> {
                tv_service_count.text = "数字增量:${it.arg1} "
            }
        }
        false
    }
    )

 
3.客户端绑定服务
调用bindService(), 传入ServiceConnection

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val intent = Intent(this, RemoteService::class.java)
        btn_bind_server.setOnClickListener {
            bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
        }

        btn_unbind_server.setOnClickListener {
            unbindService(serviceConnection)
        }
    }

 
至此,一个简单的AIDL例子就大概实现了,第一次po文,写得不好多多包涵。

上一篇 下一篇

猜你喜欢

热点阅读