pull/32/head
Administrator 5 years ago
parent 01a7bc7889
commit ed41f5a6dd
  1. 4
      app/src/main/java/io/legado/app/base/BaseViewModel.kt
  2. 57
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  3. 6
      app/src/main/java/io/legado/app/model/WebBook.kt
  4. 36
      app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt

@ -13,11 +13,11 @@ open class BaseViewModel(application: Application) : AndroidViewModel(applicatio
AnkoLogger {
fun <T> execute(block: suspend CoroutineScope.() -> T): Coroutine<T> {
return Coroutine.launch(this) { block() }
return Coroutine.async(this) { block() }
}
fun <T> submit(block: suspend CoroutineScope.() -> Deferred<T>): Coroutine<T> {
return Coroutine.launch(this) { block().await() }
return Coroutine.async(this) { block().await() }
}
fun <T> plus(coroutine: Coroutine<T>): Coroutine<T> {

@ -2,35 +2,38 @@ package io.legado.app.help.coroutine
import kotlinx.coroutines.*
class Coroutine<T>(private val scope: CoroutineScope, private val block: suspend CoroutineScope.() -> T) {
class Coroutine<T>() {
companion object {
private val DEFAULT = MainScope()
fun <T> launch(scope: CoroutineScope = DEFAULT, block: suspend CoroutineScope.() -> T): Coroutine<T> {
fun <T> async(scope: CoroutineScope = DEFAULT, block: suspend CoroutineScope.() -> T): Coroutine<T> {
return Coroutine(scope, block)
}
fun <T> plus(coroutine: Coroutine<T>): Coroutine<T>{
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 <T> plus(coroutine: Coroutine<T>): Coroutine<T> {
return Coroutine(coroutine)
}
}
private val job: Job
private var coroutine: Coroutine<T>? = null
private var job: Job? = null
init {
job = scope.launch {
executeInternal(block)
private constructor(
scope: CoroutineScope? = null,
block: (suspend CoroutineScope.() -> T)? = null
) : this() {
this.job = scope?.launch {
block?.let { executeInternal(it) }
}
}
private constructor(coroutine: Coroutine<T>) : 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<T>(private val scope: CoroutineScope, private val block: suspend
fun timeout(timeMillis: () -> Long): Coroutine<T> {
if (this.coroutine != null) {
this.coroutine!!.timeMillis = timeMillis()
} else {
this.timeMillis = timeMillis()
}
return this@Coroutine
}
fun onErrorReturn(value: () -> T?): Coroutine<T> {
if (this.coroutine != null) {
this.coroutine!!.errorReturn = Result(value())
} else {
errorReturn = Result(value())
}
return this@Coroutine
}
fun onStart(start: (() -> Unit)): Coroutine<T> {
if (this.coroutine != null) {
this.coroutine!!.start = start
} else {
this.start = start
}
return this@Coroutine
}
fun onSuccess(success: (T?) -> Unit): Coroutine<T> {
if (this.coroutine != null) {
this.coroutine!!.success = success
} else {
this.success = success
}
return this@Coroutine
}
fun onError(error: (Throwable) -> Unit): Coroutine<T> {
if (this.coroutine != null) {
this.coroutine!!.error = error
} else {
this.error = error
}
return this@Coroutine
}
fun onFinally(finally: () -> Unit): Coroutine<T> {
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) {

@ -12,7 +12,7 @@ import io.legado.app.model.webbook.BookList
class WebBook(private val bookSource: BookSource) {
fun searchBook(key: String, page: Int?): Coroutine<List<SearchBook>> {
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<IHttpGetApi>(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<SearchBook>()
return@async arrayListOf<SearchBook>()
}
}

@ -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<List<SearchBook>> = MutableLiveData()
fun search(start: (() -> Unit)? = null, finally: (() -> Unit)? = null) {
execute {
val c = execute {
val response: String = HttpHelper.getApiService<CommonHttpApi>(
"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()
}
}
}

Loading…
Cancel
Save