优化
This commit is contained in:
@@ -17,7 +17,7 @@ import splitties.init.appCtx
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.min
|
||||
|
||||
class SearchModel(private val scope: CoroutineScope, private val callBack: CallBack) {
|
||||
class SearchModel(private val scope: CoroutineScope) {
|
||||
val threadCount = AppConfig.threadCount
|
||||
private var searchPool: ExecutorCoroutineDispatcher? = null
|
||||
private var mSearchId = 0L
|
||||
@@ -26,10 +26,19 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
private var tasks = CompositeCoroutine()
|
||||
private var bookSourceList = arrayListOf<BookSource>()
|
||||
private var searchBooks = arrayListOf<SearchBook>()
|
||||
private var callBack: CallBack? = null
|
||||
|
||||
@Volatile
|
||||
private var searchIndex = -1
|
||||
|
||||
fun registerCallback(callBack: CallBack) {
|
||||
this.callBack = callBack
|
||||
}
|
||||
|
||||
fun unRegisterCallback() {
|
||||
this.callBack = null
|
||||
}
|
||||
|
||||
private fun initSearchPool() {
|
||||
searchPool?.close()
|
||||
searchPool = Executors
|
||||
@@ -37,10 +46,10 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
}
|
||||
|
||||
fun search(searchId: Long, key: String) {
|
||||
callBack.onSearchStart()
|
||||
callBack?.onSearchStart()
|
||||
if (searchId != mSearchId) {
|
||||
if (key.isEmpty()) {
|
||||
callBack.onSearchCancel()
|
||||
callBack?.onSearchCancel()
|
||||
return
|
||||
} else {
|
||||
this.searchKey = key
|
||||
@@ -53,6 +62,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
searchPage = 1
|
||||
val searchGroup = appCtx.getPrefString("searchGroup") ?: ""
|
||||
bookSourceList.clear()
|
||||
callBack?.onSearchSuccess(searchBooks)
|
||||
if (searchGroup.isBlank()) {
|
||||
bookSourceList.addAll(appDb.bookSourceDao.allEnabled)
|
||||
} else {
|
||||
@@ -103,7 +113,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
appDb.searchBookDao.insert(*items.toTypedArray())
|
||||
val precision = appCtx.getPrefBoolean(PreferKey.precisionSearch)
|
||||
mergeItems(scope, items, precision)
|
||||
callBack.onSearchSuccess(searchBooks)
|
||||
callBack?.onSearchSuccess(searchBooks)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +127,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
if (searchIndex >= bookSourceList.lastIndex
|
||||
+ min(bookSourceList.size, threadCount)
|
||||
) {
|
||||
callBack.onSearchFinish()
|
||||
callBack?.onSearchFinish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +199,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
|
||||
fun cancelSearch() {
|
||||
close()
|
||||
callBack.onSearchCancel()
|
||||
callBack?.onSearchCancel()
|
||||
}
|
||||
|
||||
fun close() {
|
||||
|
||||
@@ -148,6 +148,8 @@ class ChangeSourceDialog() : BaseDialogFragment(R.layout.dialog_change_source),
|
||||
adapter.setItems(it)
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
launch {
|
||||
appDb.bookSourceDao.flowGroupEnabled().collect {
|
||||
groups.clear()
|
||||
it.map { group ->
|
||||
|
||||
@@ -19,7 +19,6 @@ import io.legado.app.constant.AppPattern
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.Book
|
||||
import io.legado.app.data.entities.SearchBook
|
||||
import io.legado.app.data.entities.SearchKeyword
|
||||
import io.legado.app.databinding.ActivityBookSearchBinding
|
||||
import io.legado.app.lib.theme.*
|
||||
@@ -30,6 +29,7 @@ import io.legado.app.utils.*
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -195,6 +195,13 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
launch {
|
||||
viewModel.searchDataFlow
|
||||
.collect {
|
||||
adapter.setItems(it)
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
launch {
|
||||
appDb.bookSourceDao.flowGroupEnabled().collect {
|
||||
groups.clear()
|
||||
@@ -204,9 +211,6 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
|
||||
upGroupMenu()
|
||||
}
|
||||
}
|
||||
viewModel.searchBookLiveData.observe(this) {
|
||||
upSearchItems(it)
|
||||
}
|
||||
viewModel.isSearchLiveData.observe(this) {
|
||||
if (it) {
|
||||
startSearch()
|
||||
@@ -310,13 +314,6 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新搜索结果
|
||||
*/
|
||||
private fun upSearchItems(items: List<SearchBook>) {
|
||||
adapter.setItems(items)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始搜索
|
||||
*/
|
||||
|
||||
@@ -8,20 +8,47 @@ import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.SearchBook
|
||||
import io.legado.app.data.entities.SearchKeyword
|
||||
import io.legado.app.model.webBook.SearchModel
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
|
||||
class SearchViewModel(application: Application) : BaseViewModel(application), SearchModel.CallBack {
|
||||
private val searchModel = SearchModel(viewModelScope, this)
|
||||
private var upAdapterJob: Job? = null
|
||||
class SearchViewModel(application: Application) : BaseViewModel(application) {
|
||||
private val searchModel = SearchModel(viewModelScope)
|
||||
var isSearchLiveData = MutableLiveData<Boolean>()
|
||||
var searchBookLiveData = MutableLiveData<List<SearchBook>>()
|
||||
var searchKey: String = ""
|
||||
var isLoading = false
|
||||
private var searchBooks = arrayListOf<SearchBook>()
|
||||
private var searchID = 0L
|
||||
private var postTime = 0L
|
||||
|
||||
val searchDataFlow = callbackFlow {
|
||||
|
||||
val callback = object : SearchModel.CallBack {
|
||||
override fun onSearchStart() {
|
||||
isSearchLiveData.postValue(true)
|
||||
isLoading = true
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
|
||||
trySend(ArrayList(searchBooks))
|
||||
}
|
||||
|
||||
override fun onSearchFinish() {
|
||||
isSearchLiveData.postValue(false)
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
override fun onSearchCancel() {
|
||||
isSearchLiveData.postValue(false)
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
searchModel.registerCallback(callback)
|
||||
|
||||
awaitClose {
|
||||
searchModel.unRegisterCallback()
|
||||
}
|
||||
}.conflate()
|
||||
|
||||
/**
|
||||
* 开始搜索
|
||||
@@ -29,8 +56,6 @@ class SearchViewModel(application: Application) : BaseViewModel(application), Se
|
||||
fun search(key: String) {
|
||||
if ((searchKey == key) || key.isNotEmpty()) {
|
||||
searchModel.cancelSearch()
|
||||
searchBooks.clear()
|
||||
searchBookLiveData.postValue(searchBooks)
|
||||
searchID = System.currentTimeMillis()
|
||||
searchKey = key
|
||||
}
|
||||
@@ -40,42 +65,6 @@ class SearchViewModel(application: Application) : BaseViewModel(application), Se
|
||||
searchModel.search(searchID, searchKey)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun upAdapter() {
|
||||
upAdapterJob?.cancel()
|
||||
if (System.currentTimeMillis() >= postTime + 1000) {
|
||||
postTime = System.currentTimeMillis()
|
||||
searchBookLiveData.postValue(searchBooks)
|
||||
} else {
|
||||
upAdapterJob = viewModelScope.launch {
|
||||
delay(1000)
|
||||
upAdapter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSearchStart() {
|
||||
isSearchLiveData.postValue(true)
|
||||
isLoading = true
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
|
||||
this.searchBooks = searchBooks
|
||||
upAdapter()
|
||||
}
|
||||
|
||||
override fun onSearchFinish() {
|
||||
isSearchLiveData.postValue(false)
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
override fun onSearchCancel() {
|
||||
isSearchLiveData.postValue(false)
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 停止搜索
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user