优化换源

pull/341/head^2
gedoor 4 years ago
parent c4303af574
commit 1496927823
  1. 100
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt

@ -10,30 +10,35 @@ import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppPattern
import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.Book
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
import io.legado.app.utils.getPrefBoolean
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher
import org.jetbrains.anko.debug
import java.util.concurrent.CopyOnWriteArraySet
import java.util.concurrent.Executors
class ChangeSourceViewModel(application: Application) : BaseViewModel(application) {
private var searchPool =
Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher()
val threadCount = AppConfig.threadCount
private lateinit var searchPool: ExecutorCoroutineDispatcher
val handler = Handler()
val searchStateData = MutableLiveData<Boolean>()
val searchBooksLiveData = MutableLiveData<List<SearchBook>>()
var name: String = ""
var author: String = ""
private var task: Coroutine<*>? = null
private var tasks = CompositeCoroutine()
private var screenKey: String = ""
private val searchBooks = hashSetOf<SearchBook>()
private var bookSourceList = arrayListOf<BookSource>()
private val searchBooks = CopyOnWriteArraySet<SearchBook>()
private var postTime = 0L
private val sendRunnable = Runnable { upAdapter() }
@Volatile
private var searchIndex = -1
fun initData(arguments: Bundle?) {
arguments?.let { bundle ->
@ -46,13 +51,17 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
}
}
private fun initSearchPool() {
searchPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher()
}
fun loadDbSearchBook() {
execute {
App.db.searchBookDao().getByNameAuthorEnable(name, author).let {
searchBooks.addAll(it)
if (it.size <= 1) {
upAdapter()
search()
startSearch()
} else {
upAdapter()
}
@ -83,38 +92,53 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
upAdapter()
}
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(IO) {
it.forEach { searchBook ->
if (searchBook.name == name && searchBook.author == author) {
if (context.getPrefBoolean(PreferKey.changeSourceLoadToc)) {
if (searchBook.tocUrl.isEmpty()) {
loadBookInfo(searchBook.toBook())
} else {
loadChapter(searchBook.toBook())
}
private fun startSearch() {
execute {
bookSourceList.clear()
bookSourceList.addAll(App.db.bookSourceDao().allEnabled)
searchStateData.postValue(true)
initSearchPool()
for (i in 0 until threadCount) {
search()
}
}
}
private fun search() {
synchronized(this) {
searchIndex++
val source = bookSourceList[searchIndex]
val task = WebBook(source).searchBook(name, scope = this, context = searchPool)
.timeout(60000L)
.onSuccess(IO) {
it.forEach { searchBook ->
if (searchBook.name == name && searchBook.author == author) {
if (context.getPrefBoolean(PreferKey.changeSourceLoadToc)) {
if (searchBook.tocUrl.isEmpty()) {
loadBookInfo(searchBook.toBook())
} else {
searchFinish(searchBook)
loadChapter(searchBook.toBook())
}
return@onSuccess
} else {
searchFinish(searchBook)
}
return@forEach
}
}
}
}.onStart {
searchStateData.postValue(true)
}.onCancel {
searchStateData.postValue(false)
}
task?.invokeOnCompletion {
searchStateData.postValue(false)
}
.onFinally {
synchronized(this) {
if (searchIndex < bookSourceList.lastIndex) {
search()
} else {
searchIndex++
}
if (searchIndex >= bookSourceList.lastIndex + threadCount) {
searchStateData.postValue(false)
}
}
}
tasks.add(task)
}
}
@ -166,10 +190,12 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio
}
fun stopSearch() {
if (task?.isActive == true) {
task?.cancel()
if (tasks.isEmpty) {
startSearch()
} else {
search()
tasks.clear()
searchPool.close()
searchStateData.postValue(false)
}
}

Loading…
Cancel
Save