D
D
Dmtm2019-04-13 07:41:03
Android
Dmtm, 2019-04-13 07:41:03

LiveData to store the connection?

such an idea that the LiveData class is responsible for the connection after the appearance of the subscriber

class FTPClientLiveData : MutableLiveData<FTPClient>() {
    private var isConnecting = false
    private var lock = ReentrantLock()

    override fun onActive() {
        val client = value
        if (client == null || !client.isConnected) {
            try {
                lock.lock()
                if (!isConnecting) {
                    isConnecting = true
                    //async connection task
                    
                }
            } finally {
                lock.unlock()
            }
        }
    }

    override fun onInactive() {
        val client = value
        if (client != null) {
            try {
                client.logout()
                client.disconnect()
            } catch (e: Throwable) {
                e.printStackTrace()
            }
        }
    }

    override fun setValue(value: FTPClient?) {
        try {
            lock.lock()
            isConnecting = false
            super.setValue(value)
        } finally {
            lock.unlock()
        }
    }
}

What is the best way to wrap the connection establishment call itself? and where to deliver errors?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
illuzor, 2019-04-13
@iLLuzor

A very strange idea. LiveData should only be responsible for data

D
Dmtm, 2019-04-13
@Dmtm

something like this, I haven’t checked it yet, we need to think about how much explicit setValue is needed, now restarting the connection is possible by unsubscribing all-subscription

spoiler
class FTPClientLiveData : BaseLiveDate<FTPClient>() {

    override fun onActive() {
        val coroutineResult = value
        if (coroutineResult == null || coroutineResult.status != CoroutineResult.Status.LOADING ||
            (coroutineResult.data != null && coroutineResult.error == null && !coroutineResult.data.isConnected)
        ) {
            runCoroutine(this) {
                [email protected] FtpBrowserInteractor.connect(
                    App.instance.appPref.ftpServer,
                    App.instance.appPref.ftpPort,
                    App.instance.appPref.ftpLogin,
                    App.instance.appPref.ftpPassword
                )
            }

        }
    }


    override fun onInactive() {
        val coroutineResult = value
        coroutineResult?.let {
            if (coroutineResult.data != null) {
                try {
                    coroutineResult.data.logout()
                    coroutineResult.data.disconnect()
                } catch (e: Throwable) {
                    e.printStackTrace()
                }
            }
        }
    }

    override fun setValue(value: CoroutineResult<FTPClient>?) {
        //no external setting
    }
}

open class BaseLiveDate<T> : MutableLiveData<CoroutineResult<T>>() {

    protected fun <T> runCoroutine(resultLiveData: MutableLiveData<CoroutineResult<T>>, block: suspend () -> T) {
        value = CoroutineResult(
            CoroutineResult.Status.LOADING,
            null,
            null
        )

        GlobalScope.launch(Dispatchers.IO) {
            try {
                val result = block()
                resultLiveData.postValue(
                    CoroutineResult(
                        CoroutineResult.Status.COMPLETED,
                        result,
                        null
                    )
                )
            } catch (exception: Exception) {
                resultLiveData.postValue(
                    CoroutineResult(
                        CoroutineResult.Status.COMPLETED,
                        null,
                        exception
                    )
                )
            }
        }
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question