取消并发搜索,改成顺序搜索
点击打开相应页面
pull/374/head
Jason Yao 4 years ago
parent b484849369
commit 435c63f732
  1. 43
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  2. 27
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  3. 60
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchListFragment.kt
  4. 7
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchResult.kt

@ -1,5 +1,6 @@
package io.legado.app.service.help package io.legado.app.service.help
import android.util.Log
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.hankcs.hanlp.HanLP import com.hankcs.hanlp.HanLP
import io.legado.app.App import io.legado.app.App
@ -16,6 +17,7 @@ import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.ui.book.read.page.entities.TextChapter
import io.legado.app.ui.book.read.page.entities.TextPage
import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.ui.book.read.page.provider.ImageProvider import io.legado.app.ui.book.read.page.provider.ImageProvider
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -324,6 +326,46 @@ object ReadBook {
} }
} }
fun searchResultPositions(pages: List<TextPage>, contentPosition: Int): Array<Int>{
//
// calculate search result's pageIndex
var pageIndex = 0
var length = pages[pageIndex].text.length
Log.d("h11128", "page size ${pages.size}")
while (length < contentPosition){
pageIndex += 1
if (pageIndex >pages.size){
pageIndex = pages.size
break
}
length += pages[pageIndex].text.length
Log.d("h11128", "to next page , add length change to $length")
}
Log.d("h11128", "at pageindex $pageIndex")
// calculate search result's lineIndex
val currentPage = pages[pageIndex]
var lineIndex = 0
length = length - currentPage.text.length + currentPage.textLines[lineIndex].text.length
while (length < contentPosition){
lineIndex += 1
if (lineIndex >currentPage.textLines.size){
lineIndex = currentPage.textLines.size
break
}
length += currentPage.textLines[lineIndex].text.length
}
// charIndex
val currentLine = currentPage.textLines[lineIndex]
length -= currentLine.text.length
val charIndex = contentPosition - length
return arrayOf(pageIndex, lineIndex, charIndex)
}
/** /**
* 内容加载完成 * 内容加载完成
*/ */
@ -426,4 +468,5 @@ object ReadBook {
fun pageChanged() fun pageChanged()
fun contentLoadFinish() fun contentLoadFinish()
} }
} }

@ -9,6 +9,7 @@ import android.graphics.drawable.ColorDrawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.util.Log
import android.view.* import android.view.*
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.core.view.get import androidx.core.view.get
@ -48,6 +49,7 @@ import io.legado.app.ui.book.read.page.PageView
import io.legado.app.ui.book.read.page.TextPageFactory import io.legado.app.ui.book.read.page.TextPageFactory
import io.legado.app.ui.book.read.page.delegate.PageDelegate import io.legado.app.ui.book.read.page.delegate.PageDelegate
import io.legado.app.ui.book.searchContent.SearchListActivity import io.legado.app.ui.book.searchContent.SearchListActivity
import io.legado.app.ui.book.searchContent.SearchResult
import io.legado.app.ui.book.source.edit.BookSourceEditActivity import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.login.SourceLogin import io.legado.app.ui.login.SourceLogin
import io.legado.app.ui.replacerule.ReplaceRuleActivity import io.legado.app.ui.replacerule.ReplaceRuleActivity
@ -80,6 +82,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
private val requestCodeChapterList = 568 private val requestCodeChapterList = 568
private val requestCodeEditSource = 111 private val requestCodeEditSource = 111
private val requestCodeReplace = 312 private val requestCodeReplace = 312
private val requestCodeSearchResult = 123
private var menu: Menu? = null private var menu: Menu? = null
private var textActionMenu: TextActionMenu? = null private var textActionMenu: TextActionMenu? = null
@ -675,7 +678,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
override fun openSearchList() { override fun openSearchList() {
ReadBook.book?.let { ReadBook.book?.let {
startActivityForResult<SearchListActivity>( startActivityForResult<SearchListActivity>(
requestCodeChapterList, requestCodeSearchResult,
Pair("bookUrl", it.bookUrl) Pair("bookUrl", it.bookUrl)
) )
} }
@ -761,11 +764,31 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
requestCodeChapterList -> requestCodeChapterList ->
data?.getIntExtra("index", ReadBook.durChapterIndex)?.let { index -> data?.getIntExtra("index", ReadBook.durChapterIndex)?.let { index ->
if (index != ReadBook.durChapterIndex) { if (index != ReadBook.durChapterIndex) {
viewModel.openChapter(index) val pageIndex = data.getIntExtra("pageIndex", 0)
viewModel.openChapter(index, pageIndex)
}
}
requestCodeSearchResult ->
data?.getIntExtra("index", ReadBook.durChapterIndex)?.let { index ->
val contentPosition = data.getIntExtra("contentPosition", 0)
val query = data.getStringExtra("query")
ReadBook.durChapterIndex = index
ReadBook.saveRead()
ReadBook.loadContent(resetPageOffset = true)
val pages = ReadBook.curTextChapter?.pages
if (pages != null){
val positions = ReadBook.searchResultPositions(pages, contentPosition)
viewModel.openChapter(index, positions[0])
Log.d("h11128", positions[0].toString())
Log.d("h11128", positions[1].toString())
Log.d("h11128", positions[2].toString())
//page_view.curPage.selectStartMoveIndex(positions[0], positions[1], 0)
//page_view.curPage.selectEndMoveIndex(positions[0], positions[1], 0 + query!!.length )
} }
} }
requestCodeReplace -> onReplaceRuleSave() requestCodeReplace -> onReplaceRuleSave()
} }
} }
} }

@ -16,6 +16,9 @@ import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
import io.legado.app.service.help.ReadBook
import io.legado.app.ui.book.read.page.entities.TextPage
import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.ui.widget.recycler.UpLinearLayoutManager import io.legado.app.ui.widget.recycler.UpLinearLayoutManager
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.ColorUtils import io.legado.app.utils.ColorUtils
@ -37,6 +40,8 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment
lateinit var adapter: SearchListAdapter lateinit var adapter: SearchListAdapter
private lateinit var mLayoutManager: UpLinearLayoutManager private lateinit var mLayoutManager: UpLinearLayoutManager
private var searchResultCounts = 0 private var searchResultCounts = 0
private var pageSize = 0
private var searchResultList: MutableList<SearchResult> = mutableListOf()
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
viewModel.searchCallBack = this viewModel.searchCallBack = this
@ -103,39 +108,36 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment
// 按章节搜索内容 // 按章节搜索内容
if (!newText.isBlank()) { if (!newText.isBlank()) {
adapter.clearItems() adapter.clearItems()
searchResultList.clear()
searchResultCounts = 0 searchResultCounts = 0
viewModel.lastQuery = newText viewModel.lastQuery = newText
App.db.bookChapterDao().getChapterList(viewModel.bookUrl).map{ var searchResults = listOf<SearchResult>()
launch(IO) { launch(Main){
val beginTime = System.currentTimeMillis() App.db.bookChapterDao().getChapterList(viewModel.bookUrl).map{ chapter ->
if (isLocalBook val job = async(IO){
|| adapter.cacheFileNames.contains(BookHelp.formatChapterName(it)) if (isLocalBook || adapter.cacheFileNames.contains(BookHelp.formatChapterName(chapter))) {
) { searchResults = searchChapter(newText, chapter)
val searchResults = searchChapter(newText, it) Log.d("h11128", "find ${searchResults.size} results in chapter ${chapter.title}")
if (searchResults.size > 0 ){
searchResultCounts += searchResults.size
withContext(Main){
tv_current_search_info.text = "搜索结果:$searchResultCounts"
adapter.addItems(searchResults)
}
} }
} }
val finishedTime = System.currentTimeMillis() - beginTime job.await()
Log.d("h11128", "Search finished, the total time cost is $finishedTime") if (searchResults.isNotEmpty()){
Log.d("h11128", "Search finished, the total count is $searchResultCounts") Log.d("h11128", "load ${searchResults.size} results in chapter ${chapter.title}")
searchResultList.addAll(searchResults)
tv_current_search_info.text = "搜索结果:$searchResultCounts"
Log.d("h11128", "searchResultList size ${searchResultList.size}")
adapter.addItems(searchResults)
searchResults = listOf<SearchResult>()
}
} }
} }
} }
} }
private fun searchChapter(query: String, chapter: BookChapter?): MutableList<SearchResult> { private fun searchChapter(query: String, chapter: BookChapter?): List<SearchResult> {
val startTime = System.currentTimeMillis()
val searchResults: MutableList<SearchResult> = mutableListOf() val searchResults: MutableList<SearchResult> = mutableListOf()
var positions : List<Int>? = listOf() var positions : List<Int>? = listOf()
if (chapter != null){ if (chapter != null){
Log.d("h11128", "Search ${chapter.title}")
viewModel.book?.let { bookSource -> viewModel.book?.let { bookSource ->
val bookContent = BookHelp.getContent(bookSource, chapter) val bookContent = BookHelp.getContent(bookSource, chapter)
if (bookContent != null){ if (bookContent != null){
@ -169,22 +171,21 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment
positions = searchPosition(bookContent, query) positions = searchPosition(bookContent, query)
positions?.map{ positions?.map{
val construct = constructText(bookContent, it, query) val construct = constructText(bookContent, it, query)
val result = SearchResult(index = 0, val result = SearchResult(index = searchResultCounts,
text = construct[1] as String, text = construct[1] as String,
chapterTitle = chapter.title, chapterTitle = chapter.title,
query = query, query = query,
pageIndex = 0, //todo: 计算搜索结果所在的pageIndex直接跳转 pageIndex = 0, //todo: 计算搜索结果所在的pageIndex直接跳转
chapterIndex = chapter.index, chapterIndex = chapter.index,
newPosition = construct[0] as Int newPosition = construct[0] as Int,
contentPosition = it
) )
searchResultCounts += 1
searchResults.add(result) searchResults.add(result)
// Log.d("h11128", result.presentText) // Log.d("h11128", result.presentText)
} }
Log.d("h11128", "Search ${chapter.title} finished, the appeared count is ${positions!!.size}")
} }
} }
val endTime = System.currentTimeMillis() - startTime
Log.d("h11128", "Search ${chapter.title} finished, the time cost is $endTime")
} }
return searchResults return searchResults
} }
@ -222,11 +223,16 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment
get() = viewModel.book?.isLocalBook() == true get() = viewModel.book?.isLocalBook() == true
override fun openSearchResult(searchResult: SearchResult) { override fun openSearchResult(searchResult: SearchResult) {
val searchData = Intent() val searchData = Intent()
searchData.putExtra("index", searchResult.chapterIndex) searchData.putExtra("index", searchResult.chapterIndex)
searchData.putExtra("pageIndex", searchResult.pageIndex) searchData.putExtra("contentPosition", searchResult.contentPosition)
searchData.putExtra("query", searchResult.query)
Log.d("h11128","current chapter index ${searchResult.chapterIndex}")
activity?.setResult(RESULT_OK, searchData) activity?.setResult(RESULT_OK, searchData)
activity?.finish() activity?.finish()
} }
} }

@ -1,5 +1,8 @@
package io.legado.app.ui.book.searchContent package io.legado.app.ui.book.searchContent
import android.util.Log
import io.legado.app.ui.book.read.page.entities.TextPage
data class SearchResult( data class SearchResult(
var index: Int = 0, var index: Int = 0,
var text: String = "", var text: String = "",
@ -8,7 +11,8 @@ data class SearchResult(
var pageSize: Int = 0, var pageSize: Int = 0,
var chapterIndex: Int = 0, var chapterIndex: Int = 0,
var pageIndex: Int = 0, var pageIndex: Int = 0,
var newPosition: Int = 0 var newPosition: Int = 0,
var contentPosition: Int =0
) { ) {
val presentText: String val presentText: String
get(){ get(){
@ -20,4 +24,5 @@ data class SearchResult(
"<font color=#0000ff>($chapterTitle)</font>" "<font color=#0000ff>($chapterTitle)</font>"
} }
} }
Loading…
Cancel
Save