Задать вопрос
@Dmtm
Android

LiveData для хранения соединения?

такая идея, чтобы LiveData класс отвечал за соединение после появления подписчика
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()
        }
    }
}

во что лучше обернуть сам вызов установки соединения? и куда доставлять ошибки?
  • Вопрос задан
  • 79 просмотров
Подписаться 2 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 2
iLLuzor
@iLLuzor
Java, Kotlin, Android Developer
Очень странная идея. LiveData должна отвечать только за данные
Ответ написан
@Dmtm Автор вопроса
Android
примерно так, пока не проверял, надо подумать насколько нужно явное setValue, сейчас перезапуск соединения возможен через отписку всех-подписку
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) {
                return@runCoroutine 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
                    )
                )
            }
        }
    }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы