0

だから私は最初の Kotlin Android ライブラリを書こうとしています。これは、(理論的には) Network System Discovery の使用を少し簡単にするラッパーです。何が起こっているのか、私がやろうとしていることを調べます。コードの大部分を抽象化し、省略します。そのため、Android に組み込まれた NSD は、実際に使用する前に、多くのボイラープレート コードとリスナーを実装する必要があります。最新のアプローチと Kotlins の機能を利用して、これを解決しようとしました。これで、一度作成した NsdHelper クラスを使用して、サービスの登録、登録解除、検出などを行うことができます。これは、ヘルパー クラスの特定のメソッドを呼び出すリスターをラッパーで囲むことによって実現されます。

ヘルパー メソッドの例

        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
        )
    }

サービスを登録するには、必要なすべての情報を、失敗または成功の場合に実行されるラムダと共に渡します。クラスにコールバックregisterSuccessCallBackregisterFailureCallBackを格納する必要があるため、ここで問題が発生します。だからこんな感じ

typealias Success = (NsdServiceInfo?) -> Unit
typealias Failure = (java.lang.Exception) -> Unit

    // SHOULD BE PRIVATE
    var registerSuccessCallBack: Success? = null
    var registerFailureCallBack: Failure? = null

私が自分自身についてコメントしたように、それらはプライベートである必要があり、ユーザーがアクセスできるべきではありませんが、リスナーがこのように実装される方法として、単純にプライベートにすることはできません

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つの解決策を考えましたが、これに適切にアプローチする方法に関する情報をオンラインで見つけることができませんでした. 最初はリスナーを内部クラスにすることですが、それはヘルパー クラスのサイズを大幅に増加させてしまうので、気分が悪くなります。もう 1 つの解決策は、関数呼び出しでリスナーを作成し、コールバックをコンストラクターに渡すことでした。誰かがアイデアを持っているなら、これを適切に書く方法とその理由についてのアドバイスやヒントを本当に感謝します. これは、私が心に決めた中で最も挑戦的なことの 1 つです。

4

1 に答える 1