[关闭]
@cxm-2016 2016-08-17T05:13:14.000000Z 字数 2414 阅读 1623

使用BinderFactory解决AIDL多业务逻辑的问题

android no


当我们有大量业务逻辑需要使用AIDL解决的时候,不可能去为每一个业务逻辑单独开启一个Service。毕竟Service是属于四大组件之一的系统资源。为了解决这个问题,我们采取了一种工厂策略:由BinderFactory去负责生成Binder并在唯一的一个Service中返回。
举个例子:
我们需要一个服务端,该服务端由两个业务逻辑,一个是负责每5秒钟给注册到这里的客户端发送当前时间,另一个是回答客户端提出的问题。

定义AIDL文件

业务逻辑一:

  1. // ITimerCallback.aidl
  2. package aidl;
  3. // Declare any non-default types here with import statements
  4. interface ITimerCallback {
  5. void message(String message);
  6. }
  7. // ITimerHandler.aidl
  8. package aidl;
  9. // Declare any non-default types here with import statements
  10. import aidl.ITimerCallback;
  11. interface ITimerHandler {
  12. void register(ITimerCallback callback);
  13. void unregister(ITimerCallback callback);
  14. }

业务逻辑二

  1. // IAnswer.aidl
  2. package aidl;
  3. // Declare any non-default types here with import statements
  4. interface IAnswer {
  5. String answer(String question);
  6. }

单独实现每一个业务逻辑

业务一的逻辑为采用定时器,每五秒钟向注册用户发送当前时间消息

  1. class TimerBinder : ITimerHandler.Stub {
  2. constructor() {
  3. onCreate()
  4. }
  5. companion object {
  6. val listenerList = RemoteCallbackList<ITimerCallback>()//用来管理AIDL接口
  7. val task = object : TimerTask() {
  8. override fun run() {
  9. val size = listenerList.beginBroadcast()//开始遍历集合
  10. for (i in 0..size - 1) {
  11. val callback = listenerList.getBroadcastItem(i)
  12. callback.message("现在时间是: ${Date().toString()}")//给每一个注册用户发送当前时间
  13. }
  14. listenerList.finishBroadcast()//结束遍历集合
  15. }
  16. }
  17. var isRunning = false
  18. fun onCreate() {
  19. if (!isRunning) {
  20. synchronized(this, { ->
  21. if (!isRunning) {
  22. Timer().schedule(task, 5000, 5000)//五秒钟之后每隔五秒钟运行一次
  23. isRunning = true
  24. }
  25. })
  26. }
  27. }
  28. }
  29. override fun register(callback: ITimerCallback?) {
  30. listenerList.register(callback)
  31. }
  32. override fun unregister(callback: ITimerCallback?) {
  33. listenerList.unregister(callback)
  34. }
  35. }

业务二:回答客户提出的简单问题

  1. class AnswerBinder : IAnswer.Stub {
  2. val questions = mapOf(Pair("你叫什么名字", "我叫小明"), Pair("今年几岁了", "今年6岁了"))
  3. override fun answer(question: String?): String? = questions[question]
  4. }

实现BinderFactory

  1. class BinderFactory {
  2. companion object {
  3. fun newInstance(permission: String?): IBinder? {
  4. return when (permission?.toLowerCase()) {
  5. "timer" -> MessageBinder()
  6. "answer" -> AnswerBinder()
  7. else -> null
  8. }
  9. }
  10. }
  11. }

这里的逻辑很简单,就是通过关键字判断需要创建哪一种Binder对象

实现BinderDiapatchService

  1. class BinderDiapatchService : Service() {
  2. override fun onBind(intent: Intent?): IBinder? {
  3. val permission = intent?.getStringExtra("permission")
  4. return BinderFactory.newInstance(permission)
  5. }
  6. }

这个Service是不是看起来干净了许多,因为我们已经将全部的业务逻辑都通过BinderFactory分发出去了。

这时候客户端想要连接的话,就只是需要给Intent设置相应的参数就能获取到对应的Binder对象了

  1. private fun bindService() {
  2. val intent = Intent("chenxiaomo")
  3. intent.putExtra("permission", "Timer")
  4. bindService(intent, conn, Context.BIND_AUTO_CREATE)
  5. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注