@cxm-2016
2016-08-17T05:13:14.000000Z
字数 2414
阅读 2151
android no
当我们有大量业务逻辑需要使用AIDL解决的时候,不可能去为每一个业务逻辑单独开启一个Service。毕竟Service是属于四大组件之一的系统资源。为了解决这个问题,我们采取了一种工厂策略:由BinderFactory去负责生成Binder并在唯一的一个Service中返回。
举个例子:
我们需要一个服务端,该服务端由两个业务逻辑,一个是负责每5秒钟给注册到这里的客户端发送当前时间,另一个是回答客户端提出的问题。
业务逻辑一:
// ITimerCallback.aidlpackage aidl;// Declare any non-default types here with import statementsinterface ITimerCallback {void message(String message);}// ITimerHandler.aidlpackage aidl;// Declare any non-default types here with import statementsimport aidl.ITimerCallback;interface ITimerHandler {void register(ITimerCallback callback);void unregister(ITimerCallback callback);}
业务逻辑二
// IAnswer.aidlpackage aidl;// Declare any non-default types here with import statementsinterface IAnswer {String answer(String question);}
业务一的逻辑为采用定时器,每五秒钟向注册用户发送当前时间消息
class TimerBinder : ITimerHandler.Stub {constructor() {onCreate()}companion object {val listenerList = RemoteCallbackList<ITimerCallback>()//用来管理AIDL接口val task = object : TimerTask() {override fun run() {val size = listenerList.beginBroadcast()//开始遍历集合for (i in 0..size - 1) {val callback = listenerList.getBroadcastItem(i)callback.message("现在时间是: ${Date().toString()}")//给每一个注册用户发送当前时间}listenerList.finishBroadcast()//结束遍历集合}}var isRunning = falsefun onCreate() {if (!isRunning) {synchronized(this, { ->if (!isRunning) {Timer().schedule(task, 5000, 5000)//五秒钟之后每隔五秒钟运行一次isRunning = true}})}}}override fun register(callback: ITimerCallback?) {listenerList.register(callback)}override fun unregister(callback: ITimerCallback?) {listenerList.unregister(callback)}}
业务二:回答客户提出的简单问题
class AnswerBinder : IAnswer.Stub {val questions = mapOf(Pair("你叫什么名字", "我叫小明"), Pair("今年几岁了", "今年6岁了"))override fun answer(question: String?): String? = questions[question]}
class BinderFactory {companion object {fun newInstance(permission: String?): IBinder? {return when (permission?.toLowerCase()) {"timer" -> MessageBinder()"answer" -> AnswerBinder()else -> null}}}}
这里的逻辑很简单,就是通过关键字判断需要创建哪一种Binder对象
class BinderDiapatchService : Service() {override fun onBind(intent: Intent?): IBinder? {val permission = intent?.getStringExtra("permission")return BinderFactory.newInstance(permission)}}
这个Service是不是看起来干净了许多,因为我们已经将全部的业务逻辑都通过BinderFactory分发出去了。
这时候客户端想要连接的话,就只是需要给Intent设置相应的参数就能获取到对应的Binder对象了
private fun bindService() {val intent = Intent("chenxiaomo")intent.putExtra("permission", "Timer")bindService(intent, conn, Context.BIND_AUTO_CREATE)}
