0

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.

Nikola-Milovic
  • 1,393
  • 1
  • 12
  • 35

1 Answers1

0

Use internal instead of private so they will be accessible only in the module.

JavierSegoviaCordoba
  • 6,531
  • 9
  • 37
  • 51