多线程显示校验详细信息

用flow每300ms刷新,去除eventbus的使用
pull/1254/head
Jason Yao 3 years ago
parent e70211de73
commit 59c42c4506
  1. 33
      app/src/main/java/io/legado/app/model/Debug.kt
  2. 23
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  3. 2
      app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt
  4. 31
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  5. 11
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt
  6. 2
      app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugModel.kt
  7. 4
      app/src/main/java/io/legado/app/web/SourceDebugWebSocket.kt

@ -2,6 +2,7 @@ package io.legado.app.model
import android.annotation.SuppressLint
import io.legado.app.data.entities.*
import io.legado.app.help.AppConfig
import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.model.rss.Rss
import io.legado.app.model.webBook.WebBook
@ -11,14 +12,15 @@ import io.legado.app.utils.msg
import kotlinx.coroutines.CoroutineScope
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.collections.HashMap
object Debug {
var callback: Callback? = null
private var debugSource: String? = null
private val tasks: CompositeCoroutine = CompositeCoroutine()
val debugMessageMap = ConcurrentHashMap<String, String>()
private var isChecking: Boolean = false
val debugMessageMap = HashMap<String, String>()
private val debugTimeMap = HashMap<String, Long>()
var isChecking: Boolean = false
@SuppressLint("ConstantLocale")
private val DEBUG_TIME_FORMAT = SimpleDateFormat("[mm:ss.SSS]", Locale.getDefault())
@ -33,8 +35,20 @@ object Debug {
showTime: Boolean = true,
state: Int = 1
) {
if (AppConfig.checkSourceMessage) {
if (isChecking && sourceUrl != null && (msg ?: "").length < 30) {
var printMsg = msg ?: ""
if (isHtml) {
printMsg = HtmlFormatter.format(msg)
}
if (showTime && debugTimeMap[sourceUrl] != null) {
val time = DEBUG_TIME_FORMAT.format(Date(System.currentTimeMillis() - debugTimeMap[sourceUrl]!!))
printMsg = "$time $printMsg"
debugMessageMap[sourceUrl] = printMsg
}
} else {
callback?.let {
if ((debugSource != sourceUrl || !print) && !isChecking) return
if ((debugSource != sourceUrl || !print)) return
var printMsg = msg ?: ""
if (isHtml) {
printMsg = HtmlFormatter.format(msg)
@ -44,9 +58,7 @@ object Debug {
printMsg = "$time $printMsg"
}
it.printLog(state, printMsg)
if (sourceUrl != null && printMsg.length < 30) {
debugMessageMap[sourceUrl] = printMsg
callback?.postCheckMessageEvent(sourceUrl)
}
}
}
}
@ -66,13 +78,12 @@ object Debug {
}
fun startChecking(source: BookSource) {
startTime = System.currentTimeMillis()
isChecking = true
debugMessageMap[source.bookSourceUrl] = "开始校验"
debugTimeMap[source.bookSourceUrl] = System.currentTimeMillis()
debugMessageMap[source.bookSourceUrl] = "${DEBUG_TIME_FORMAT.format(Date(0))} 开始校验"
}
fun finishChecking() {
callback = null
isChecking = false
}
@ -261,7 +272,5 @@ object Debug {
interface Callback {
fun printLog(state: Int, msg: String)
fun postCheckMessageEvent(sourceUrl: String)
}
}

@ -30,7 +30,7 @@ class CheckSourceService : BaseService() {
private val checkedIds = ArrayList<String>()
private var processIndex = 0
private var notificationMsg = ""
private var debugCallback : Debug.Callback? = null
private val showCheckSourceMessage = AppConfig.checkSourceMessage
private val notificationBuilder by lazy {
NotificationCompat.Builder(this, AppConst.channelIdReadAloud)
.setSmallIcon(R.drawable.ic_network_check)
@ -50,18 +50,6 @@ class CheckSourceService : BaseService() {
override fun onCreate() {
super.onCreate()
notificationMsg = getString(R.string.start)
if (AppConfig.checkSourceMessage) {
debugCallback = object : Debug.Callback {
override fun printLog(state: Int, msg: String) {}
@Synchronized
override fun postCheckMessageEvent(sourceUrl: String) {
postEvent(EventBus.CHECK_SOURCE_MESSAGE, sourceUrl)
}
}
Debug.callback = debugCallback
threadCount = 1
}
upNotification()
}
@ -120,7 +108,7 @@ class CheckSourceService : BaseService() {
fun check(source: BookSource) {
execute(context = searchCoroutine) {
if (AppConfig.checkSourceMessage) {
if (showCheckSourceMessage) {
Debug.startChecking(source)
}
val webBook = WebBook(source)
@ -152,9 +140,8 @@ class CheckSourceService : BaseService() {
"error:${it.localizedMessage}
${source.bookSourceComment}"
""".trimIndent()
debugCallback?.let {
if (showCheckSourceMessage) {
Debug.debugMessageMap[source.bookSourceUrl] = Debug.debugMessageMap[source.bookSourceUrl] + " 失败"
postEvent(EventBus.CHECK_SOURCE_MESSAGE, source.bookSourceUrl)
}
appDb.bookSourceDao.update(source)
}.onSuccess(searchCoroutine) {
@ -164,11 +151,9 @@ class CheckSourceService : BaseService() {
?.filterNot {
it.startsWith("error:")
}?.joinToString("\n")
debugCallback?.let { debugCallback
if (showCheckSourceMessage) {
Debug.debugMessageMap[source.bookSourceUrl] = Debug.debugMessageMap[source.bookSourceUrl] + " 成功"
postEvent(EventBus.CHECK_SOURCE_MESSAGE, source.bookSourceUrl)
}
appDb.bookSourceDao.update(source)
}.onFinally(searchCoroutine) {
onNext(source.bookSourceUrl, source.bookSourceName)

@ -51,8 +51,6 @@ class BookSourceDebugModel(application: Application) : BaseViewModel(application
}
}
override fun postCheckMessageEvent(sourceUrl: String) {}
override fun onCleared() {
super.onCleared()
Debug.cancelDebug(true)

@ -21,6 +21,7 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ActivityBookSourceBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig
import io.legado.app.help.LocalConfig
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.ATH
@ -40,9 +41,8 @@ import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.io.File
class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceViewModel>(),
@ -340,6 +340,9 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
}
}
CheckSource.start(this@BookSourceActivity, adapter.selection)
if(AppConfig.checkSourceMessage) {
checkMessageRefreshJob().start()
}
}
noButton()
}.show()
@ -446,13 +449,23 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
}
}
}
observeEvent<String>(EventBus.CHECK_SOURCE_MESSAGE) { bookSourceUrl ->
sourceFlowJob?.cancel()
sourceFlowJob = launch {
appDb.bookSourceDao.flowSearch(bookSourceUrl)
.map { adapter.getItems().indexOf(it[0]) }
.collect {
adapter.notifyItemChanged(it, bundleOf(Pair(EventBus.CHECK_SOURCE_MESSAGE, null))) }
}
private fun checkMessageRefreshJob(): Job {
val firstIndex = adapter.getItems().indexOf(adapter.selection.first())
val lastIndex = adapter.getItems().indexOf(adapter.selection.last())
Debug.isChecking = true
return async(start = CoroutineStart.LAZY) {
flow {
while (true) {
emit(Debug.isChecking)
delay(300L)
}
}.collect {
adapter.notifyItemRangeChanged(firstIndex, lastIndex + 1, bundleOf(Pair("checkSourceMessage", null)))
if (!it) {
this.cancel()
}
}
}
}

@ -13,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.constant.EventBus
import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ItemBookSourceBinding
import io.legado.app.lib.theme.backgroundColor
@ -116,10 +115,14 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
payload.keySet().map {
when (it) {
"selected" -> cbBookSource.isChecked = selected.contains(item)
EventBus.CHECK_SOURCE_MESSAGE -> {
"checkSourceMessage" -> {
ivDebugText.text = Debug.debugMessageMap[item.bookSourceUrl] ?: ""
ivDebugText.visibility = if(ivDebugText.text.toString().length > 1) View.VISIBLE else View.GONE
ivProgressBar.visibility = if(ivDebugText.text.toString().contains(Regex("成功|失败"))) View.GONE else View.VISIBLE
val isEmpty = ivDebugText.text.toString().isEmpty()
ivDebugText.visibility =
if (!isEmpty) View.VISIBLE else View.GONE
ivProgressBar.visibility =
if (ivDebugText.text.toString().contains(Regex("成功|失败")) || isEmpty) View.GONE
else View.VISIBLE
}
}
}

@ -44,8 +44,6 @@ class RssSourceDebugModel(application: Application) : BaseViewModel(application)
}
}
override fun postCheckMessageEvent(sourceUrl: String) {}
override fun onCleared() {
super.onCleared()
Debug.cancelDebug(true)

@ -95,8 +95,4 @@ class SourceDebugWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) :
}
}
override fun postCheckMessageEvent(sourceUrl: String) {
TODO("Not yet implemented")
}
}

Loading…
Cancel
Save