优化换源,换封面

pull/348/head 3.20.082919
gedoor 4 years ago
parent fcf7f3720e
commit 4a359c48a8
  1. 104
      app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt
  2. 3
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt

@ -6,24 +6,31 @@ import androidx.lifecycle.MutableLiveData
import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppPattern
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook
import io.legado.app.help.AppConfig
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.model.webBook.WebBook
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher
import java.util.concurrent.Executors
import kotlin.math.min
class ChangeCoverViewModel(application: Application) : BaseViewModel(application) {
private var searchPool =
Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher()
private val threadCount = AppConfig.threadCount
private var searchPool: ExecutorCoroutineDispatcher? = null
var name: String = ""
var author: String = ""
private var task: Coroutine<*>? = null
private var tasks = CompositeCoroutine()
private var bookSourceList = arrayListOf<BookSource>()
val searchStateData = MutableLiveData<Boolean>()
val searchBooksLiveData = MutableLiveData<List<SearchBook>>()
private val searchBooks = ArrayList<SearchBook>()
@Volatile
private var searchIndex = -1
fun initData(arguments: Bundle?) {
arguments?.let { bundle ->
bundle.getString("name")?.let {
@ -35,13 +42,18 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
}
}
private fun initSearchPool() {
searchPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher()
searchIndex = -1
}
fun loadDbSearchBook() {
execute {
App.db.searchBookDao().getEnableHasCover(name, author).let {
searchBooks.addAll(it)
if (it.size <= 1) {
searchBooksLiveData.postValue(searchBooks)
search()
startSearch()
} else {
searchBooksLiveData.postValue(searchBooks)
}
@ -49,50 +61,70 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
}
}
fun search() {
task = execute {
val bookSourceList = App.db.bookSourceDao().allEnabled
for (item in bookSourceList) {
//task取消时自动取消 by (scope = this@execute)
WebBook(item).searchBook(name, scope = this@execute, context = searchPool)
.timeout(30000L)
.onSuccess(Dispatchers.IO) {
if (it.isNotEmpty()) {
val searchBook = it[0]
if (searchBook.name == name && searchBook.author == author
&& !searchBook.coverUrl.isNullOrEmpty()
) {
App.db.searchBookDao().insert(searchBook)
if (!searchBooks.contains(searchBook)) {
searchBooks.add(searchBook)
searchBooksLiveData.postValue(searchBooks)
}
}
}
}
}
}.onStart {
private fun startSearch() {
execute {
bookSourceList.clear()
bookSourceList.addAll(App.db.bookSourceDao().allEnabled)
searchStateData.postValue(true)
}.onCancel {
searchStateData.postValue(false)
initSearchPool()
for (i in 0 until threadCount) {
search()
}
}
}
task?.invokeOnCompletion {
searchStateData.postValue(false)
private fun search() {
synchronized(this) {
if (searchIndex >= bookSourceList.lastIndex) {
return
}
searchIndex++
val source = bookSourceList[searchIndex]
val task = WebBook(source).searchBook(name, scope = this, context = searchPool!!)
.timeout(60000L)
.onSuccess(Dispatchers.IO) {
if (it.isNotEmpty()) {
val searchBook = it[0]
if (searchBook.name == name && searchBook.author == author
&& !searchBook.coverUrl.isNullOrEmpty()
) {
App.db.searchBookDao().insert(searchBook)
if (!searchBooks.contains(searchBook)) {
searchBooks.add(searchBook)
searchBooksLiveData.postValue(searchBooks)
}
}
}
}
.onFinally {
synchronized(this) {
if (searchIndex < bookSourceList.lastIndex) {
search()
} else {
searchIndex++
}
if (searchIndex >= bookSourceList.lastIndex + min(bookSourceList.size,
threadCount)
) {
searchStateData.postValue(false)
}
}
}
tasks.add(task)
}
}
fun stopSearch() {
if (task?.isActive == true) {
task?.cancel()
if (tasks.isEmpty) {
startSearch()
} else {
search()
tasks.clear()
}
}
override fun onCleared() {
super.onCleared()
searchPool.close()
searchPool?.close()
}
}

@ -25,7 +25,7 @@ import java.util.concurrent.Executors
import kotlin.math.min
class ChangeSourceViewModel(application: Application) : BaseViewModel(application) {
val threadCount = AppConfig.threadCount
private val threadCount = AppConfig.threadCount
private var searchPool: ExecutorCoroutineDispatcher? = null
val handler = Handler()
val searchStateData = MutableLiveData<Boolean>()
@ -54,6 +54,7 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
private fun initSearchPool() {
searchPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher()
searchIndex = -1
}
fun loadDbSearchBook() {

Loading…
Cancel
Save