Answer the question
In order to leave comments, you need to log in
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()
}
}
}
Answer the question
In order to leave comments, you need to log in
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
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 questionAsk a Question
731 491 924 answers to any question