diff --git a/app/src/main/java/io/legado/app/base/BaseViewModel.kt b/app/src/main/java/io/legado/app/base/BaseViewModel.kt index dcd19b586..f21cbdf06 100644 --- a/app/src/main/java/io/legado/app/base/BaseViewModel.kt +++ b/app/src/main/java/io/legado/app/base/BaseViewModel.kt @@ -13,11 +13,11 @@ open class BaseViewModel(application: Application) : AndroidViewModel(applicatio AnkoLogger { fun execute(block: suspend CoroutineScope.() -> T): Coroutine { - return Coroutine.launch(this) { block() } + return Coroutine.async(this) { block() } } fun submit(block: suspend CoroutineScope.() -> Deferred): Coroutine { - return Coroutine.launch(this) { block().await() } + return Coroutine.async(this) { block().await() } } fun plus(coroutine: Coroutine): Coroutine { diff --git a/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt b/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt index 6a471cdb7..686d6b9fc 100644 --- a/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt +++ b/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt @@ -2,35 +2,38 @@ package io.legado.app.help.coroutine import kotlinx.coroutines.* -class Coroutine(private val scope: CoroutineScope, private val block: suspend CoroutineScope.() -> T) { +class Coroutine() { companion object { private val DEFAULT = MainScope() - fun launch(scope: CoroutineScope = DEFAULT, block: suspend CoroutineScope.() -> T): Coroutine { + fun async(scope: CoroutineScope = DEFAULT, block: suspend CoroutineScope.() -> T): Coroutine { return Coroutine(scope, block) } - fun plus(coroutine: Coroutine): Coroutine{ - return Coroutine(coroutine.scope, coroutine.block) - .timeout{ coroutine.timeMillis?:0 } - .onErrorReturn { coroutine.errorReturn?.value } - .onStart { coroutine.start } - .onSuccess { coroutine.success } - .onError { coroutine.error } - .onFinally { coroutine.finally } + fun plus(coroutine: Coroutine): Coroutine { + return Coroutine(coroutine) } } - private val job: Job - - init { - job = scope.launch { - executeInternal(block) + private var coroutine: Coroutine? = null + private var job: Job? = null + + private constructor( + scope: CoroutineScope? = null, + block: (suspend CoroutineScope.() -> T)? = null + ) : this() { + this.job = scope?.launch { + block?.let { executeInternal(it) } } } + private constructor(coroutine: Coroutine) : this() { + this.coroutine = coroutine + this.job = coroutine.job + } + private var start: (() -> Unit)? = null private var success: ((T?) -> Unit)? = null private var error: ((Throwable) -> Unit)? = null @@ -42,38 +45,62 @@ class Coroutine(private val scope: CoroutineScope, private val block: suspend fun timeout(timeMillis: () -> Long): Coroutine { - this.timeMillis = timeMillis() + if (this.coroutine != null) { + this.coroutine!!.timeMillis = timeMillis() + } else { + this.timeMillis = timeMillis() + } return this@Coroutine } fun onErrorReturn(value: () -> T?): Coroutine { - errorReturn = Result(value()) + if (this.coroutine != null) { + this.coroutine!!.errorReturn = Result(value()) + } else { + errorReturn = Result(value()) + } return this@Coroutine } fun onStart(start: (() -> Unit)): Coroutine { - this.start = start + if (this.coroutine != null) { + this.coroutine!!.start = start + } else { + this.start = start + } return this@Coroutine } fun onSuccess(success: (T?) -> Unit): Coroutine { - this.success = success + if (this.coroutine != null) { + this.coroutine!!.success = success + } else { + this.success = success + } return this@Coroutine } fun onError(error: (Throwable) -> Unit): Coroutine { - this.error = error + if (this.coroutine != null) { + this.coroutine!!.error = error + } else { + this.error = error + } return this@Coroutine } fun onFinally(finally: () -> Unit): Coroutine { - this.finally = finally + if (this.coroutine != null) { + this.coroutine!!.finally = finally + } else { + this.finally = finally + } return this@Coroutine } //取消当前任务 fun cancel(cause: CancellationException? = null) { - job.cancel(cause) + job?.cancel(cause) } private suspend fun executeInternal(block: suspend CoroutineScope.() -> T) { diff --git a/app/src/main/java/io/legado/app/model/WebBook.kt b/app/src/main/java/io/legado/app/model/WebBook.kt index 7fb067215..675e0c8d2 100644 --- a/app/src/main/java/io/legado/app/model/WebBook.kt +++ b/app/src/main/java/io/legado/app/model/WebBook.kt @@ -12,7 +12,7 @@ import io.legado.app.model.webbook.BookList class WebBook(private val bookSource: BookSource) { fun searchBook(key: String, page: Int?): Coroutine> { - return Coroutine.launch { + return Coroutine.async { bookSource.getSearchRule().searchUrl?.let { searchUrl -> val analyzeUrl = AnalyzeUrl(searchUrl) val response = when { @@ -29,9 +29,9 @@ class WebBook(private val bookSource: BookSource) { else -> HttpHelper.getApiService(analyzeUrl.baseUrl) .getMap(analyzeUrl.url, analyzeUrl.fieldMap, analyzeUrl.headerMap).await() } - return@launch BookList.analyzeBookList(response, bookSource, analyzeUrl) + return@async BookList.analyzeBookList(response, bookSource, analyzeUrl) } - return@launch arrayListOf() + return@async arrayListOf() } } diff --git a/app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt b/app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt index 2674ce70e..5c7465884 100644 --- a/app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt @@ -12,26 +12,23 @@ import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.http.HttpHelper import io.legado.app.model.WebBook import kotlinx.coroutines.delay +import kotlinx.coroutines.launch class SearchViewModel(application: Application) : BaseViewModel(application) { val searchBooks: LiveData> = MutableLiveData() fun search(start: (() -> Unit)? = null, finally: (() -> Unit)? = null) { - execute { + val c = execute { val response: String = HttpHelper.getApiService( "http://www.baidu.com" ).get("http://www.baidu.com").await() - delay(4000L) - - Log.e("TAG1", Thread.currentThread().name) + delay(2000L) response } - .timeout { 100L } - .onErrorReturn { "error return" } .onStart { Log.e("TAG!", "start") start?.let { it() } @@ -49,7 +46,32 @@ class SearchViewModel(application: Application) : BaseViewModel(application) { } } - plus(WebBook(BookSource()).searchBook("keyword", 1)) + val c2 = plus(c) +// .timeout { 100L } +// .onErrorReturn { "error return2" } + .onStart { + Log.e("TAG!", "start2") + start?.let { it() } + } + .onSuccess { + Log.e("TAG!", "success2: $it") + } + .onError { + Log.e("TAG!", "error2: $it") + } + .onFinally { + Log.e("TAG!", "finally2") + if (finally != null) { + finally() + } + } + + launch { + + delay(1500L) + c2.cancel() + + } } }