kunfei %!s(int64=4) %!d(string=hai) anos
pai
achega
8aa574dca2

+ 57 - 33
app/src/main/java/io/legado/app/data/entities/BookSource.kt

@@ -8,6 +8,10 @@ import io.legado.app.constant.BookType
 import io.legado.app.data.entities.rule.*
 import io.legado.app.help.SourceAnalyzer
 import io.legado.app.utils.*
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
+import kotlinx.coroutines.withContext
 import kotlinx.parcelize.IgnoredOnParcel
 import kotlinx.parcelize.Parcelize
 import java.io.InputStream
@@ -89,46 +93,66 @@ data class BookSource(
         return bookSourceUrl
     }
 
-    @delegate:Transient
-    @delegate:Ignore
+    @Ignore
     @IgnoredOnParcel
-    val exploreKinds: List<ExploreKind> by lazy {
-        val exploreUrl = exploreUrl ?: return@lazy emptyList()
-        val kinds = arrayListOf<ExploreKind>()
-        var ruleStr = exploreUrl
-        if (ruleStr.isNotBlank()) {
-            kotlin.runCatching {
-                if (exploreUrl.startsWith("<js>", false)
-                    || exploreUrl.startsWith("@js:", false)
-                ) {
-                    val aCache = ACache.get("explore")
-                    ruleStr = aCache.getAsString(bookSourceUrl) ?: ""
-                    if (ruleStr.isBlank()) {
-                        val jsStr = if (exploreUrl.startsWith("@")) {
-                            exploreUrl.substring(4)
-                        } else {
-                            exploreUrl.substring(4, exploreUrl.lastIndexOf("<"))
+    private var exploreKinds: List<ExploreKind>? = null
+
+    @Ignore
+    @IgnoredOnParcel
+    private val mutex = Mutex()
+
+    suspend fun exploreKinds(): List<ExploreKind> {
+        exploreKinds?.let { return it }
+        val exploreUrl = exploreUrl
+        if (exploreUrl.isNullOrBlank()) {
+            return emptyList()
+        }
+        mutex.withLock {
+            exploreKinds?.let { return it }
+            val kinds = arrayListOf<ExploreKind>()
+            var ruleStr: String = exploreUrl
+            withContext(IO) {
+                kotlin.runCatching {
+                    if (exploreUrl.startsWith("<js>", false)
+                        || exploreUrl.startsWith("@js:", false)
+                    ) {
+                        val aCache = ACache.get("explore")
+                        ruleStr = aCache.getAsString(bookSourceUrl) ?: ""
+                        if (ruleStr.isBlank()) {
+                            val jsStr = if (exploreUrl.startsWith("@")) {
+                                exploreUrl.substring(4)
+                            } else {
+                                exploreUrl.substring(4, exploreUrl.lastIndexOf("<"))
+                            }
+                            ruleStr = evalJS(jsStr).toString().trim()
+                            aCache.put(bookSourceUrl, ruleStr)
                         }
-                        ruleStr = evalJS(jsStr).toString().trim()
-                        aCache.put(bookSourceUrl, ruleStr)
-                    }
-                }
-                if (ruleStr.isJsonArray()) {
-                    GSON.fromJsonArray<ExploreKind>(ruleStr).getOrThrow()?.let {
-                        kinds.addAll(it)
                     }
-                } else {
-                    ruleStr.split("(&&|\n)+".toRegex()).forEach { kindStr ->
-                        val kindCfg = kindStr.split("::")
-                        kinds.add(ExploreKind(kindCfg.first(), kindCfg.getOrNull(1)))
+                    if (ruleStr.isJsonArray()) {
+                        GSON.fromJsonArray<ExploreKind>(ruleStr).getOrThrow()?.let {
+                            kinds.addAll(it)
+                        }
+                    } else {
+                        ruleStr.split("(&&|\n)+".toRegex()).forEach { kindStr ->
+                            val kindCfg = kindStr.split("::")
+                            kinds.add(ExploreKind(kindCfg.first(), kindCfg.getOrNull(1)))
+                        }
                     }
+                }.onFailure {
+                    kinds.add(ExploreKind("ERROR:${it.localizedMessage}", it.stackTraceToString()))
+                    it.printOnDebug()
                 }
-            }.onFailure {
-                kinds.add(ExploreKind("ERROR:${it.localizedMessage}", it.stackTraceToString()))
-                it.printOnDebug()
             }
+            exploreKinds = kinds
+            return kinds
+        }
+    }
+
+    suspend fun clearExploreKindsCache() {
+        withContext(IO) {
+            ACache.get("explore").remove(bookSourceUrl)
+            exploreKinds = null
         }
-        return@lazy kinds
     }
 
     override fun hashCode(): Int {

+ 1 - 1
app/src/main/java/io/legado/app/service/CheckSourceService.kt

@@ -155,7 +155,7 @@ class CheckSourceService : BaseService() {
             }
             //校验发现书籍
             if (CheckSource.checkDiscovery) {
-                val exs = source.exploreKinds
+                val exs = source.exploreKinds()
                 var url: String? = null
                 for (ex in exs) {
                     url = ex.url

+ 12 - 10
app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugActivity.kt

@@ -88,16 +88,6 @@ class BookSourceDebugActivity : VMBaseActivity<ActivitySourceDebugBinding, BookS
                 binding.textMy.text = it
             }
         }
-        viewModel.bookSource?.exploreKinds?.firstOrNull {
-            !it.url.isNullOrBlank()
-        }?.let {
-            binding.textFx.text = "${it.title}::${it.url}"
-            if (it.title.startsWith("ERROR:")) {
-                adapter.addItem("获取发现出错\n${it.url}")
-                openOrCloseHelp(false)
-                searchView.clearFocus()
-            }
-        }
         binding.textMy.onClick {
             searchView.setQuery(binding.textMy.text, true)
         }
@@ -138,6 +128,18 @@ class BookSourceDebugActivity : VMBaseActivity<ActivitySourceDebugBinding, BookS
                 }
             }
         }
+        launch {
+            viewModel.bookSource?.exploreKinds()?.firstOrNull {
+                !it.url.isNullOrBlank()
+            }?.let {
+                binding.textFx.text = "${it.title}::${it.url}"
+                if (it.title.startsWith("ERROR:")) {
+                    adapter.addItem("获取发现出错\n${it.url}")
+                    openOrCloseHelp(false)
+                    searchView.clearFocus()
+                }
+            }
+        }
     }
 
     /**

+ 3 - 4
app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt

@@ -56,7 +56,7 @@ class ExploreAdapter(context: Context, val callBack: CallBack) :
                     callBack.scrollTo(scrollTo)
                 }
                 Coroutine.async(callBack.scope) {
-                    item.exploreKinds
+                    item.exploreKinds()
                 }.onSuccess { kindList ->
                     upKindList(flexbox, item.bookSourceUrl, kindList)
                 }.onFinally {
@@ -167,9 +167,9 @@ class ExploreAdapter(context: Context, val callBack: CallBack) :
                     putExtra("key", source.bookSourceUrl)
                 }
                 R.id.menu_refresh -> Coroutine.async(callBack.scope) {
-                    ACache.get("explore").remove(source.bookSourceUrl)
+                    source.clearExploreKindsCache()
                 }.onSuccess {
-                    callBack.refreshData()
+                    notifyItemChanged(position)
                 }
                 R.id.menu_del -> callBack.deleteSource(source)
             }
@@ -181,7 +181,6 @@ class ExploreAdapter(context: Context, val callBack: CallBack) :
 
     interface CallBack {
         val scope: CoroutineScope
-        fun refreshData()
         fun scrollTo(pos: Int)
         fun openExplore(sourceUrl: String, title: String, exploreUrl: String?)
         fun editSource(sourceUrl: String)

+ 0 - 4
app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt

@@ -157,10 +157,6 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
         }
     }
 
-    override fun refreshData() {
-        upExploreData(searchView.query?.toString())
-    }
-
     override fun scrollTo(pos: Int) {
         (binding.rvFind.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(pos, 0)
     }