所以我一直在尝试写我的第一个Kotlin Android库。这是一个包装器,(理论上)应该可以让使用网络系统发现变得更容易一些。来介绍一下正在发生的事情和我正在尝试做的事情。我会抽象出很多代码,不说了。所以androids内置的NSD在实际使用之前需要实现大量的锅炉模板代码和监听器。我试图用现代的方法和利用Kotlins的特性来解决这个问题。所以现在我有一个NsdHelper类,你只需要创建一次,然后用它来注册、取消注册、发现服务等等。这是通过在列表器周围设置包装器来实现的,包装器可以调用helper类中的特定方法。
Helper方法的例子
sName: String,
sType: String,
sPort: Int,
success: (NsdServiceInfo?) -> Unit,
failure: (Exception?) -> Unit
) {
val serviceInfo = NsdServiceInfo().apply {
serviceName = sName
serviceType = sType
port = sPort
}
registerSuccessCallBack = success
registerFailureCallBack = failure
mNsdManager.registerService(
serviceInfo,
NsdManager.PROTOCOL_DNS_SD,
registrationListener
)
}
要注册一个服务,你需要传递所有必要的信息,以及在失败或成功时执行的lambdas。问题出现在这里,因为我必须存储回调。registerSuccessCallback 和 注册失败回访 的类中。所以它看起来像这样
typealias Success = (NsdServiceInfo?) -> Unit
typealias Failure = (java.lang.Exception) -> Unit
// SHOULD BE PRIVATE
var registerSuccessCallBack: Success? = null
var registerFailureCallBack: Failure? = null
就像我自己评论的那样,它们应该是私有的,不应该被用户访问,但我不能简单地把它们变成私有的,因为Listeners的实现方式是这样的。
class NsdKRegistrationListener(val nsdKelper: NsdKelper) : NsdManager.RegistrationListener{
companion object {
private const val ERROR_SOURCE = "android.net.nsd.NsdHelper.RegistrationListener"
}
override fun onUnregistrationFailed(serviceInfo: NsdServiceInfo?, errorCode: Int) {
Log.d("TAG", "UnRegistration failed $errorCode")
nsdKelper.unRegisterFailureCallBack?.invoke(UnRegistrationFailedException(errorCode.toString()))
}
override fun onServiceUnregistered(serviceInfo: NsdServiceInfo?) {
Log.d("TAG", "Unregistered service $serviceInfo")
nsdKelper.unRegisterSuccessCallBack?.invoke(serviceInfo)
}
所以它们必须是公开的,才能被听众访问。我想了2个解决方案,但在网上找不到任何关于如何正确处理这个问题的信息。首先是将Listeners做成内部类,但这样会大大增加Helper类的大小,感觉不对。另一种解决方案是在函数调用中创建监听器,并将回调传入其构造函数中。如果有谁有想法,我真的很感谢一些建议或提示,如何正确地写这个,为什么这么做。这是我下定决心要做的最具挑战性的事情之一。
使用 internal
而不是 private
所以它们只能在模块中访问。