kunfei 4 лет назад
Родитель
Сommit
754bd2d727

+ 1 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -1,5 +1,6 @@
 <component name="InspectionProjectProfileManager">
   <settings>
+    <option name="PROJECT_PROFILE" value="Default" />
     <option name="USE_PROJECT_PROFILE" value="false" />
     <version value="1.0" />
   </settings>

+ 1 - 0
app/src/main/assets/updateLog.md

@@ -14,6 +14,7 @@
 **2022/07/12**
 
 * 针对自建webDav进行优化,解决一些问题 by 821938089
+* 修复全文搜索新关键词时,老关键词搜索没有停止的bug
 
 **2022/07/10**
 

+ 34 - 22
app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt

@@ -7,6 +7,7 @@ import androidx.activity.viewModels
 import androidx.appcompat.widget.SearchView
 import io.legado.app.R
 import io.legado.app.base.VMBaseActivity
+import io.legado.app.constant.AppLog
 import io.legado.app.constant.EventBus
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.Book
@@ -25,6 +26,8 @@ import io.legado.app.utils.observeEvent
 import io.legado.app.utils.postEvent
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.ensureActive
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
@@ -41,6 +44,7 @@ class SearchContentActivity :
         binding.titleBar.findViewById(R.id.search_view)
     }
     private var durChapterIndex = 0
+    private var searchJob: Job? = null
 
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         val bbg = bottomBackground
@@ -133,35 +137,43 @@ class SearchContentActivity :
     fun startContentSearch(query: String) {
         // 按章节搜索内容
         if (query.isNotBlank()) {
+            searchJob?.cancel()
             adapter.clearItems()
             viewModel.searchResultList.clear()
             viewModel.searchResultCounts = 0
             viewModel.lastQuery = query
-            launch {
-                withContext(IO) {
-                    appDb.bookChapterDao.getChapterList(viewModel.bookUrl)
-                }.forEach { bookChapter ->
-                    binding.refreshProgressBar.isAutoLoading = true
-                    val searchResults = withContext(IO) {
-                        if (isLocalBook || viewModel.cacheChapterNames.contains(bookChapter.getFileName())) {
-                            viewModel.searchChapter(query, bookChapter)
-                        } else {
-                            null
+            searchJob = launch {
+                kotlin.runCatching {
+                    withContext(IO) {
+                        appDb.bookChapterDao.getChapterList(viewModel.bookUrl)
+                    }.forEach { bookChapter ->
+                        ensureActive()
+                        binding.refreshProgressBar.isAutoLoading = true
+                        val searchResults = withContext(IO) {
+                            if (isLocalBook || viewModel.cacheChapterNames.contains(bookChapter.getFileName())) {
+                                viewModel.searchChapter(this, query, bookChapter)
+                            } else {
+                                null
+                            }
+                        }
+                        binding.tvCurrentSearchInfo.text =
+                            this@SearchContentActivity.getString(R.string.search_content_size) + ": ${viewModel.searchResultCounts}"
+                        ensureActive()
+                        if (searchResults != null && searchResults.isNotEmpty()) {
+                            viewModel.searchResultList.addAll(searchResults)
+                            binding.refreshProgressBar.isAutoLoading = false
+                            adapter.addItems(searchResults)
                         }
                     }
-                    binding.tvCurrentSearchInfo.text =
-                        this@SearchContentActivity.getString(R.string.search_content_size) + ": ${viewModel.searchResultCounts}"
-                    if (searchResults != null && searchResults.isNotEmpty()) {
-                        viewModel.searchResultList.addAll(searchResults)
-                        binding.refreshProgressBar.isAutoLoading = false
-                        adapter.addItems(searchResults)
+                    binding.refreshProgressBar.isAutoLoading = false
+                    if (viewModel.searchResultCounts == 0) {
+                        val noSearchResult =
+                            SearchResult(resultText = getString(R.string.search_content_empty))
+                        adapter.addItem(noSearchResult)
                     }
-                }
-                binding.refreshProgressBar.isAutoLoading = false
-                if (viewModel.searchResultCounts == 0) {
-                    val noSearchResult =
-                        SearchResult(resultText = getString(R.string.search_content_empty))
-                    adapter.addItem(noSearchResult)
+                }.onFailure {
+                    binding.refreshProgressBar.isAutoLoading = false
+                    AppLog.put("全文搜索出错\n${it.localizedMessage}", it)
                 }
             }
         }

+ 13 - 3
app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentViewModel.kt

@@ -10,7 +10,9 @@ import io.legado.app.data.entities.BookChapter
 import io.legado.app.help.BookHelp
 import io.legado.app.help.ContentProcessor
 import io.legado.app.help.config.AppConfig
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ensureActive
 import kotlinx.coroutines.withContext
 
 class SearchContentViewModel(application: Application) : BaseViewModel(application) {
@@ -35,11 +37,16 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
         }
     }
 
-    suspend fun searchChapter(query: String, chapter: BookChapter?): List<SearchResult> {
+    suspend fun searchChapter(
+        scope: CoroutineScope,
+        query: String,
+        chapter: BookChapter?
+    ): List<SearchResult> {
         val searchResultsWithinChapter: MutableList<SearchResult> = mutableListOf()
         if (chapter != null) {
             book?.let { book ->
                 val chapterContent = BookHelp.getContent(book, chapter)
+                scope.ensureActive()
                 if (chapterContent != null) {
                     //先搜索没有启用净化的正文
                     withContext(Dispatchers.IO) {
@@ -48,6 +55,7 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
                             2 -> ChineseUtils.s2t(chapter.title)
                             else -> chapter.title
                         }
+                        scope.ensureActive()
                         mContent = contentProcessor!!.getContent(
                             book, chapter, chapterContent,
                             chineseConvert = true,
@@ -55,8 +63,9 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
                             useReplace = false
                         ).joinToString("")
                     }
-                    val positions = searchPosition(query)
+                    val positions = searchPosition(scope, query)
                     positions.forEachIndexed { index, position ->
+                        scope.ensureActive()
                         val construct = getResultAndQueryIndex(mContent, position, query)
                         val result = SearchResult(
                             resultCountWithinChapter = index,
@@ -76,7 +85,7 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
         return searchResultsWithinChapter
     }
 
-    private suspend fun searchPosition(pattern: String): List<Int> {
+    private suspend fun searchPosition(scope: CoroutineScope, pattern: String): List<Int> {
         val position: MutableList<Int> = mutableListOf()
         var index = mContent.indexOf(pattern)
         if (index >= 0) {
@@ -86,6 +95,7 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
                 index = mContent.indexOf(pattern)
             }
             while (index >= 0) {
+                scope.ensureActive()
                 position.add(index)
                 index = mContent.indexOf(pattern, index + 1)
             }