feat: 优化代码

pull/167/head
kunfei 5 years ago
parent 1a699bb4b8
commit a67156b0cf
  1. 33
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  2. 5
      app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt
  3. 5
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt
  4. 6
      app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt

@ -6,7 +6,7 @@ import kotlin.coroutines.CoroutineContext
class Coroutine<T>( class Coroutine<T>(
scope: CoroutineScope, val scope: CoroutineScope,
context: CoroutineContext = Dispatchers.IO, context: CoroutineContext = Dispatchers.IO,
block: suspend CoroutineScope.() -> T block: suspend CoroutineScope.() -> T
) { ) {
@ -31,6 +31,7 @@ class Coroutine<T>(
private var success: Callback<T?>? = null private var success: Callback<T?>? = null
private var error: Callback<Throwable>? = null private var error: Callback<Throwable>? = null
private var finally: VoidCallback? = null private var finally: VoidCallback? = null
private var cancel: VoidCallback? = null
private var timeMillis: Long? = null private var timeMillis: Long? = null
private var errorReturn: Result<T>? = null private var errorReturn: Result<T>? = null
@ -45,7 +46,7 @@ class Coroutine<T>(
get() = job.isCompleted get() = job.isCompleted
init { init {
this.job = executeInternal(scope, context, block) this.job = executeInternal(context, block)
} }
fun timeout(timeMillis: () -> Long): Coroutine<T> { fun timeout(timeMillis: () -> Long): Coroutine<T> {
@ -100,9 +101,28 @@ class Coroutine<T>(
return this@Coroutine return this@Coroutine
} }
fun onCancel(
context: CoroutineContext? = null,
block: suspend CoroutineScope.() -> Unit
): Coroutine<T> {
this.cancel = VoidCallback(context, block)
return this@Coroutine
}
//取消当前任务 //取消当前任务
fun cancel(cause: CancellationException? = null) { fun cancel(cause: CancellationException? = null) {
job.cancel(cause) job.cancel(cause)
cancel?.let {
scope.plus(Dispatchers.Main).launch {
if (null == it.context) {
it.block.invoke(scope)
} else {
withContext(scope.coroutineContext.plus(it.context)) {
it.block.invoke(this)
}
}
}
}
} }
fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle { fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle {
@ -110,7 +130,6 @@ class Coroutine<T>(
} }
private fun executeInternal( private fun executeInternal(
scope: CoroutineScope,
context: CoroutineContext, context: CoroutineContext,
block: suspend CoroutineScope.() -> T block: suspend CoroutineScope.() -> T
): Job { ): Job {
@ -118,24 +137,30 @@ class Coroutine<T>(
try { try {
start?.let { dispatchVoidCallback(this, it) } start?.let { dispatchVoidCallback(this, it) }
val value = executeBlock(scope, context, timeMillis ?: 0L, block) val value = executeBlock(scope, context, timeMillis ?: 0L, block)
if (isActive) {
success?.let { dispatchCallback(this, value, it) } success?.let { dispatchCallback(this, value, it) }
}
} catch (e: Throwable) { } catch (e: Throwable) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
e.printStackTrace() e.printStackTrace()
} }
val consume: Boolean = errorReturn?.value?.let { value -> val consume: Boolean = errorReturn?.value?.let { value ->
if (isActive) {
success?.let { dispatchCallback(this, value, it) } success?.let { dispatchCallback(this, value, it) }
}
true true
} ?: false } ?: false
if (!consume) { if (!consume && isActive) {
error?.let { dispatchCallback(this, e, it) } error?.let { dispatchCallback(this, e, it) }
} }
} finally { } finally {
if (isActive) {
finally?.let { dispatchVoidCallback(this, it) } finally?.let { dispatchVoidCallback(this, it) }
} }
} }
} }
}
private suspend inline fun dispatchVoidCallback(scope: CoroutineScope, callback: VoidCallback) { private suspend inline fun dispatchVoidCallback(scope: CoroutineScope, callback: VoidCallback) {
if (null == callback.context) { if (null == callback.context) {

@ -51,7 +51,6 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
fun search() { fun search() {
task = execute { task = execute {
searchStateData.postValue(true)
val bookSourceList = App.db.bookSourceDao().allEnabled val bookSourceList = App.db.bookSourceDao().allEnabled
for (item in bookSourceList) { for (item in bookSourceList) {
//task取消时自动取消 by (scope = this@execute) //task取消时自动取消 by (scope = this@execute)
@ -72,6 +71,10 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
} }
} }
} }
}.onStart {
searchStateData.postValue(true)
}.onCancel {
searchStateData.postValue(false)
} }
task?.invokeOnCompletion { task?.invokeOnCompletion {

@ -72,7 +72,6 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
fun search() { fun search() {
task = execute { task = execute {
searchStateData.postValue(true)
val bookSourceList = App.db.bookSourceDao().allEnabled val bookSourceList = App.db.bookSourceDao().allEnabled
for (item in bookSourceList) { for (item in bookSourceList) {
//task取消时自动取消 by (scope = this@execute) //task取消时自动取消 by (scope = this@execute)
@ -95,6 +94,10 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
} }
} }
} }
}.onStart {
searchStateData.postValue(true)
}.onCancel {
searchStateData.postValue(false)
} }
task?.invokeOnCompletion { task?.invokeOnCompletion {

@ -43,7 +43,6 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
searchKey = key searchKey = key
searchBooks.clear() searchBooks.clear()
} }
isSearchLiveData.postValue(true)
task = execute { task = execute {
val searchGroup = context.getPrefString("searchGroup") ?: "" val searchGroup = context.getPrefString("searchGroup") ?: ""
val bookSourceList = if (searchGroup.isBlank()) { val bookSourceList = if (searchGroup.isBlank()) {
@ -71,6 +70,11 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
} }
} }
} }
}.onStart {
isSearchLiveData.postValue(true)
}.onCancel {
isSearchLiveData.postValue(false)
isLoading = false
} }
task?.invokeOnCompletion { task?.invokeOnCompletion {

Loading…
Cancel
Save