Coroutine timeout

pull/32/head
Administrator 5 years ago
parent 9dd651e36a
commit 929255a171
  1. 2
      app/src/main/java/io/legado/app/base/BaseViewModel.kt
  2. 67
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  3. 2
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  4. 24
      app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt

@ -12,7 +12,7 @@ open class BaseViewModel(application: Application) : AndroidViewModel(applicatio
AnkoLogger { AnkoLogger {
fun <T> execute(domain: suspend CoroutineScope.() -> T): Coroutine<T> { fun <T> execute(domain: suspend CoroutineScope.() -> T): Coroutine<T> {
return Coroutine.with<T>(this).execute(domain) return Coroutine.with(this) { domain() }
} }
override fun onCleared() { override fun onCleared() {

@ -1,13 +1,20 @@
package io.legado.app.help.coroutine package io.legado.app.help.coroutine
import android.util.Log
import kotlinx.coroutines.* import kotlinx.coroutines.*
class Coroutine<T>(private val scope: CoroutineScope) { class Coroutine<T>(scope: CoroutineScope, private val domain: suspend CoroutineScope.() -> T) {
companion object { companion object {
fun <T> with(scope: CoroutineScope): Coroutine<T> { fun <T> with(scope: CoroutineScope, domain: suspend CoroutineScope.() -> T): Coroutine<T> {
return Coroutine(scope) return Coroutine(scope, domain)
}
}
init {
scope.launch {
executeInternal(domain)
} }
} }
@ -16,28 +23,10 @@ class Coroutine<T>(private val scope: CoroutineScope) {
private var error: ((Throwable) -> Unit)? = null private var error: ((Throwable) -> Unit)? = null
private var finally: (() -> Unit)? = null private var finally: (() -> Unit)? = null
fun execute(domain: suspend CoroutineScope.() -> T): Coroutine<T> { private var timeMillis: Long? = null
scope.launch {
tryCatch(
{
start?.let { it() }
val result: T? = withContext(Dispatchers.IO) {
domain()
}
success?.let { it(result) }
}, fun timeout(timeMillis: Long): Coroutine<T> {
{ e -> this.timeMillis = timeMillis
error?.let { it(e) }
},
{
finally?.let { it() }
})
}
return this@Coroutine return this@Coroutine
} }
@ -61,6 +50,36 @@ class Coroutine<T>(private val scope: CoroutineScope) {
return this@Coroutine return this@Coroutine
} }
private suspend fun executeInternal(domain: suspend CoroutineScope.() -> T) {
tryCatch(
{
start?.let { it() }
val result = if (timeMillis != null && timeMillis!! > 0) {
withTimeout(timeMillis!!) {
executeDomain(domain)
}
} else {
executeDomain(domain)
}
success?.let { it(result) }
},
{ e ->
error?.let { it(e) }
},
{
finally?.let { it() }
})
}
private suspend fun executeDomain(domain: suspend CoroutineScope.() -> T): T? {
return withContext(Dispatchers.IO) {
Log.e("TAG!", "executeDomain")
domain()
}
}
private suspend fun tryCatch( private suspend fun tryCatch(
tryBlock: suspend CoroutineScope.() -> Unit, tryBlock: suspend CoroutineScope.() -> Unit,
errorBlock: (suspend CoroutineScope.(Throwable) -> Unit)? = null, errorBlock: (suspend CoroutineScope.(Throwable) -> Unit)? = null,

@ -152,7 +152,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
if (isUrl && !TextUtils.isEmpty(it)) { if (isUrl && !TextUtils.isEmpty(it)) {
val urlList = ArrayList<String>() val urlList = ArrayList<String>()
if (result is List<*>) { if (result is List<*>) {
for (url in result) { for (url in result as List<*>) {
val absoluteURL = NetworkUtils.getAbsoluteURL(it, url.toString()) val absoluteURL = NetworkUtils.getAbsoluteURL(it, url.toString())
if (!urlList.contains(absoluteURL)) { if (!urlList.contains(absoluteURL)) {
urlList.add(absoluteURL) urlList.add(absoluteURL)

@ -9,6 +9,7 @@ import io.legado.app.data.api.CommonHttpApi
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.HttpHelper
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeout
import org.jetbrains.anko.error import org.jetbrains.anko.error
class SearchViewModel(application: Application) : BaseViewModel(application) { class SearchViewModel(application: Application) : BaseViewModel(application) {
@ -17,16 +18,16 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
fun search(start: (() -> Unit)? = null, finally: (() -> Unit)? = null) { fun search(start: (() -> Unit)? = null, finally: (() -> Unit)? = null) {
execute { execute {
val response: String = HttpHelper.getApiService<CommonHttpApi>( // val response: String = HttpHelper.getApiService<CommonHttpApi>(
"http://www.baidu.com" // "http://www.baidu.com"
).get("http://www.baidu.com").await() // ).get("http://www.baidu.com").await()
//
delay(4000L) // delay(4000L)
//
Log.e("TAG1", Thread.currentThread().name) // Log.e("TAG1", Thread.currentThread().name)
response null
} }.timeout(30000L)
.onStart { .onStart {
Log.e("TAG!", "start") Log.e("TAG!", "start")
} }
@ -34,12 +35,11 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
Log.e("TAG!", "success: $it") Log.e("TAG!", "success: $it")
} }
.onError { .onError {
error { "${it.message}" } Log.e("TAG!", "error: $it")
} }
.onFinally { .onFinally {
Log.e("TAG!", "finally") Log.e("TAG!", "finally")
} }
} }
} }

Loading…
Cancel
Save