Merge pull request #2136 from 821938089/opt-source-manager

优化书源管理和校验
pull/2143/head
kunfei 2 years ago committed by GitHub
commit 1ed59318f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      app/src/main/java/io/legado/app/base/BaseService.kt
  2. 10
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  3. 10
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  4. 2
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  5. 19
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt

@ -6,10 +6,7 @@ import android.os.IBinder
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import io.legado.app.help.LifecycleHelp import io.legado.app.help.LifecycleHelp
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
abstract class BaseService : Service(), CoroutineScope by MainScope() { abstract class BaseService : Service(), CoroutineScope by MainScope() {
@ -17,8 +14,9 @@ abstract class BaseService : Service(), CoroutineScope by MainScope() {
fun <T> execute( fun <T> execute(
scope: CoroutineScope = this, scope: CoroutineScope = this,
context: CoroutineContext = Dispatchers.IO, context: CoroutineContext = Dispatchers.IO,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T block: suspend CoroutineScope.() -> T
) = Coroutine.async(scope, context) { block() } ) = Coroutine.async(scope, context, start) { block() }
@CallSuper @CallSuper
override fun onCreate() { override fun onCreate() {

@ -12,6 +12,7 @@ import kotlin.coroutines.CoroutineContext
class Coroutine<T>( class Coroutine<T>(
val scope: CoroutineScope, val scope: CoroutineScope,
context: CoroutineContext = Dispatchers.IO, context: CoroutineContext = Dispatchers.IO,
val startOption: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T block: suspend CoroutineScope.() -> T
) { ) {
@ -22,9 +23,10 @@ class Coroutine<T>(
fun <T> async( fun <T> async(
scope: CoroutineScope = DEFAULT, scope: CoroutineScope = DEFAULT,
context: CoroutineContext = Dispatchers.IO, context: CoroutineContext = Dispatchers.IO,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T block: suspend CoroutineScope.() -> T
): Coroutine<T> { ): Coroutine<T> {
return Coroutine(scope, context, block) return Coroutine(scope, context, start, block)
} }
} }
@ -135,11 +137,15 @@ class Coroutine<T>(
return job.invokeOnCompletion(handler) return job.invokeOnCompletion(handler)
} }
fun start() {
job.start()
}
private fun executeInternal( private fun executeInternal(
context: CoroutineContext, context: CoroutineContext,
block: suspend CoroutineScope.() -> T block: suspend CoroutineScope.() -> T
): Job { ): Job {
return (scope + Dispatchers.Main).launch { return (scope + Dispatchers.Main).launch(start = startOption) {
try { try {
start?.let { dispatchVoidCallback(this, it) } start?.let { dispatchVoidCallback(this, it) }
ensureActive() ensureActive()

@ -24,10 +24,8 @@ import io.legado.app.utils.activityPendingIntent
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import io.legado.app.utils.servicePendingIntent import io.legado.app.utils.servicePendingIntent
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.launch
import org.mozilla.javascript.WrappedException import org.mozilla.javascript.WrappedException
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.min import kotlin.math.min
@ -122,7 +120,7 @@ class CheckSourceService : BaseService() {
*校验书源 *校验书源
*/ */
private fun check(source: BookSource) { private fun check(source: BookSource) {
execute(context = searchCoroutine) { execute(context = searchCoroutine, start = CoroutineStart.LAZY) {
Debug.startChecking(source) Debug.startChecking(source)
var searchWord = CheckSource.keyword var searchWord = CheckSource.keyword
source.ruleSearch?.checkKeyWord?.let { source.ruleSearch?.checkKeyWord?.let {
@ -162,7 +160,7 @@ class CheckSourceService : BaseService() {
} }
} }
if (url.isNullOrBlank()) { if (url.isNullOrBlank()) {
source.addGroup("发现规则为空") source.addGroup("发现规则为空")
} else { } else {
source.removeGroup("发现规则为空") source.removeGroup("发现规则为空")
val exploreBooks = WebBook.exploreBookAwait(this, source, url) val exploreBooks = WebBook.exploreBookAwait(this, source, url)
@ -194,7 +192,7 @@ class CheckSourceService : BaseService() {
source.respondTime = Debug.getRespondTime(source.bookSourceUrl) source.respondTime = Debug.getRespondTime(source.bookSourceUrl)
appDb.bookSourceDao.update(source) appDb.bookSourceDao.update(source)
onNext(source.bookSourceUrl, source.bookSourceName) onNext(source.bookSourceUrl, source.bookSourceName)
} }.start()
} }
/** /**

@ -531,7 +531,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
/** /**
* 保持亮屏 * 保持亮屏
*/ */
fun keepScreenOn(on: Boolean) { private fun keepScreenOn(on: Boolean) {
val isScreenOn = (window.attributes.flags and WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0 val isScreenOn = (window.attributes.flags and WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0
if (on == isScreenOn) return if (on == isScreenOn) return
if (on) { if (on) {

@ -32,7 +32,6 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
private val selected = linkedSetOf<BookSource>() private val selected = linkedSetOf<BookSource>()
private val selectedPosition = linkedSetOf<Int>()
val selection: List<BookSource> val selection: List<BookSource>
get() { get() {
@ -143,10 +142,8 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
if (view.isPressed) { if (view.isPressed) {
if (checked) { if (checked) {
selected.add(it) selected.add(it)
selectedPosition.add(holder.layoutPosition)
} else { } else {
selected.remove(it) selected.remove(it)
selectedPosition.remove(holder.layoutPosition)
} }
callBack.upCountView() callBack.upCountView()
} }
@ -219,22 +216,19 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
} }
fun selectAll() { fun selectAll() {
getItems().forEachIndexed { index, it -> getItems().forEach {
selected.add(it) selected.add(it)
selectedPosition.add(index)
} }
notifyItemRangeChanged(0, itemCount, bundleOf(Pair("selected", null))) notifyItemRangeChanged(0, itemCount, bundleOf(Pair("selected", null)))
callBack.upCountView() callBack.upCountView()
} }
fun revertSelection() { fun revertSelection() {
getItems().forEachIndexed { index, it -> getItems().forEach {
if (selected.contains(it)) { if (selected.contains(it)) {
selected.remove(it) selected.remove(it)
selectedPosition.remove(index)
} else { } else {
selected.add(it) selected.add(it)
selectedPosition.add(index)
} }
} }
notifyItemRangeChanged(0, itemCount, bundleOf(Pair("selected", null))) notifyItemRangeChanged(0, itemCount, bundleOf(Pair("selected", null)))
@ -242,13 +236,18 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
} }
fun checkSelectedInterval() { fun checkSelectedInterval() {
val selectedPosition = linkedSetOf<Int>()
getItems().forEachIndexed { index, it ->
if (selected.contains(it)) {
selectedPosition.add(index)
}
}
val minPosition = Collections.min(selectedPosition) val minPosition = Collections.min(selectedPosition)
val maxPosition = Collections.max(selectedPosition) val maxPosition = Collections.max(selectedPosition)
val itemCount = maxPosition - minPosition + 1 val itemCount = maxPosition - minPosition + 1
for (i in minPosition..maxPosition) { for (i in minPosition..maxPosition) {
getItem(i)?.let { getItem(i)?.let {
selected.add(it) selected.add(it)
selectedPosition.add(i)
} }
} }
notifyItemRangeChanged(minPosition, itemCount, bundleOf(Pair("selected", null))) notifyItemRangeChanged(minPosition, itemCount, bundleOf(Pair("selected", null)))
@ -296,10 +295,8 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
getItem(position)?.let { getItem(position)?.let {
if (isSelected) { if (isSelected) {
selected.add(it) selected.add(it)
selectedPosition.add(position)
} else { } else {
selected.remove(it) selected.remove(it)
selectedPosition.remove(position)
} }
notifyItemChanged(position, bundleOf(Pair("selected", null))) notifyItemChanged(position, bundleOf(Pair("selected", null)))
callBack.upCountView() callBack.upCountView()

Loading…
Cancel
Save