pull/32/head
Administrator 5 years ago
parent cc7816949f
commit 189ed326dc
  1. 11
      app/src/main/java/io/legado/app/help/coroutine/CompositeCoroutine.kt
  2. 44
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  3. 2
      app/src/main/java/io/legado/app/help/coroutine/CoroutineContainer.kt
  4. 4
      app/src/main/java/io/legado/app/ui/search/SearchActivity.kt
  5. 28
      app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt
  6. 1
      app/src/main/res/layout/activity_search.xml

@ -1,5 +1,7 @@
package io.legado.app.help.coroutine
import android.util.Log
class CompositeCoroutine : CoroutineContainer {
private var resources: HashSet<Coroutine<*>>? = null
@ -76,10 +78,11 @@ class CompositeCoroutine : CoroutineContainer {
resources = null
}
set?.forEach {
runCatching {
it.cancel()
}
Log.e("TAG", "size: ${set?.size}")
set?.forEachIndexed { index, coroutine ->
Log.e("TAG", "index: $index")
coroutine.cancel()
}
}
}

@ -44,8 +44,8 @@ class Coroutine<T>() {
scope: CoroutineScope,
block: suspend CoroutineScope.() -> T
) : this() {
this.job = scope.launch {
executeInternal(block)
this.job = scope.plus(Dispatchers.Main).launch {
executeInternal(this@launch, block)
}
}
@ -119,55 +119,51 @@ class Coroutine<T>() {
//取消当前任务
fun cancel(cause: CancellationException? = null) {
job?.cancelChildren(cause)
job?.cancel(cause)
}
private suspend fun executeInternal(block: suspend CoroutineScope.() -> T) {
private suspend fun executeInternal(scope: CoroutineScope, block: suspend CoroutineScope.() -> T) {
tryCatch(
{
start?.invoke(this)
start?.invoke(scope)
val result = executeBlockIO(block, timeMillis ?: 0L)
success?.invoke(this, result)
success?.invoke(scope, result)
},
{ e ->
val consume: Boolean = errorReturn?.value?.let { value ->
success?.invoke(this, value)
success?.invoke(scope, value)
true
} ?: false
if (!consume) {
error?.invoke(this, e)
error?.invoke(scope, e)
}
},
{
finally?.invoke(this)
finally?.invoke(scope)
})
}
private suspend fun executeBlockIO(block: suspend CoroutineScope.() -> T, timeMillis: Long): T? {
val result: T = withContext(Dispatchers.IO) {
val b = block()
execute?.invoke(this, b)
b
val execution = withContext(Dispatchers.IO) {
val result = block()
execute?.invoke(this, result)
result
}
return if (timeMillis > 0L) withTimeout(timeMillis) { result } else result
return if (timeMillis > 0L) withTimeout(timeMillis) { execution } else execution
}
private suspend fun tryCatch(
tryBlock: suspend CoroutineScope.() -> Unit,
errorBlock: (suspend CoroutineScope.(Throwable) -> Unit)? = null,
finallyBlock: (suspend CoroutineScope.() -> Unit)? = null
tryBlock: suspend () -> Unit,
errorBlock: (suspend (Throwable) -> Unit)? = null,
finallyBlock: (suspend () -> Unit)? = null
) {
try {
coroutineScope { tryBlock() }
tryBlock()
} catch (e: Throwable) {
coroutineScope { errorBlock?.invoke(this, e) }
errorBlock?.invoke(e)
} finally {
coroutineScope { finallyBlock?.invoke(this) }
finallyBlock?.invoke()
}
}

@ -1,6 +1,6 @@
package io.legado.app.help.coroutine
interface CoroutineContainer {
internal interface CoroutineContainer {
fun add(coroutine: Coroutine<*>): Boolean

@ -11,6 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.data.entities.SearchBook
import io.legado.app.data.entities.SearchShow
import io.legado.app.lib.theme.ATH
import io.legado.app.utils.getViewModel
@ -44,14 +45,13 @@ class SearchActivity : VMBaseActivity<SearchViewModel>(R.layout.activity_search)
viewModel.search(it, { startTime ->
content_view.showContentView()
initData(startTime)
}, {
})
}
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
if(newText.isNullOrBlank()) viewModel.stop()
return false
}

@ -3,7 +3,6 @@ package io.legado.app.ui.search
import android.app.Application
import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.WebBook
@ -12,18 +11,24 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
var searchPage = 0
fun search(key: String, start: ((startTime: Long) -> Unit)? = null, finally: (() -> Unit)? = null) {
fun search(
key: String,
start: ((startTime: Long) -> Unit)? = null,
finally: (() -> Unit)? = null
) {
if (key.isEmpty()) return
task?.cancel()
start?.invoke(System.currentTimeMillis())
task = execute {//onCleared时自动取消
task = execute {
//onCleared时自动取消
val bookSourceList = App.db.bookSourceDao().allEnabled
for (item in bookSourceList) {
//task取消时自动取消 by (scope = this@execute)
WebBook(item).searchBook(key, searchPage, scope = this)
.onExecute { searchBookS ->
searchBookS?.let {
App.db.searchBookDao().insert(*it.toTypedArray())
WebBook(item).searchBook(key, searchPage, scope = this@execute)
.timeout { 30000L }
.onExecute {
it?.let { list ->
App.db.searchBookDao().insert(*list.toTypedArray())
}
}
}
@ -32,4 +37,13 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
it.printStackTrace()
}
}
fun stop() {
task?.cancel()
}
override fun onCleared() {
super.onCleared()
task?.cancel()
}
}

@ -11,6 +11,7 @@
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentInsetStartWithNavigation="0dp"
app:layout_constraintTop_toTopOf="parent"
app:title="搜索"/>

Loading…
Cancel
Save