So I've been trying to write my first Kotlin Android Library. It's a wrapper that (in theory) should make using Network System Discovery a bit easier. To go over what is happening and what I am trying to do. I'll abstract much of the code and leave it out. So the androids built-in NSD requires a lot of boilerplate code and listeners to be implemented before actually using it. I tried to solve this using modern approaches and utilizing Kotlins features. So now I have a NsdHelper class that you create once and use it to register, unregister, discover services and so on. This is achieved by having wrapper around the listers, that call specific methods in the helper class.
Example of a Helper method
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
)
}
To register a service you pass all the necessary information together with lambdas that will be executed in the case of failure or success. The problem arises here, because I have to store callbacks registerSuccessCallBack and registerFailureCallBack in the class. So it looks like this
typealias Success = (NsdServiceInfo?) -> Unit
typealias Failure = (java.lang.Exception) -> Unit
// SHOULD BE PRIVATE
var registerSuccessCallBack: Success? = null
var registerFailureCallBack: Failure? = null
As I commented for myself, they should be private and they shouldn't be accessible to the user, but I cannot simply make them private as the way Listeners are implemented like this
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)
}
So they have to be public to be accessed by the listeners. I've thought of 2 solutions but couldn't find any info online of how to approach this properly. First is to make the Listeners inner classes but that would drastically increase the size of the Helper class and it just feels wrong. The other solution was to create the listeners in the function call and pass the callbacks into their constructor. If anyone has an idea I'd really appreciate some advice or tips on how to write this properly and why so. This has been one of the most challenging things I've set my mind to.