This commit is contained in:
kunfei
2023-08-01 10:36:05 +08:00
parent 6f53273a53
commit a14a3cfdd8
34 changed files with 168 additions and 125 deletions
@@ -25,9 +25,6 @@ import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.TitleBar import io.legado.app.ui.widget.TitleBar
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
abstract class BaseActivity<VB : ViewBinding>( abstract class BaseActivity<VB : ViewBinding>(
@@ -36,7 +33,7 @@ abstract class BaseActivity<VB : ViewBinding>(
private val toolBarTheme: Theme = Theme.Auto, private val toolBarTheme: Theme = Theme.Auto,
private val transparent: Boolean = false, private val transparent: Boolean = false,
private val imageBg: Boolean = true private val imageBg: Boolean = true
) : AppCompatActivity(), CoroutineScope by MainScope() { ) : AppCompatActivity() {
protected abstract val binding: VB protected abstract val binding: VB
@@ -97,11 +94,6 @@ abstract class BaseActivity<VB : ViewBinding>(
setupSystemBar() setupSystemBar()
} }
override fun onDestroy() {
super.onDestroy()
cancel()
}
abstract fun onActivityCreated(savedInstanceState: Bundle?) abstract fun onActivityCreated(savedInstanceState: Bundle?)
final override fun onCreateOptionsMenu(menu: Menu): Boolean { final override fun onCreateOptionsMenu(menu: Menu): Boolean {
@@ -6,7 +6,9 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart import io.legado.app.data.entities.BookSourcePart
import io.legado.app.utils.cnCompare import io.legado.app.utils.cnCompare
import io.legado.app.utils.splitNotBlank import io.legado.app.utils.splitNotBlank
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@Dao @Dao
@@ -293,18 +295,18 @@ interface BookSourceDao {
fun flowGroups(): Flow<List<String>> { fun flowGroups(): Flow<List<String>> {
return flowGroupsUnProcessed().map { list -> return flowGroupsUnProcessed().map { list ->
dealGroups(list) dealGroups(list)
} }.flowOn(IO)
} }
fun flowExploreGroups(): Flow<List<String>> { fun flowExploreGroups(): Flow<List<String>> {
return flowExploreGroupsUnProcessed().map { list -> return flowExploreGroupsUnProcessed().map { list ->
dealGroups(list) dealGroups(list)
} }.flowOn(IO)
} }
fun flowEnabledGroups(): Flow<List<String>> { fun flowEnabledGroups(): Flow<List<String>> {
return flowEnabledGroupsUnProcessed().map { list -> return flowEnabledGroupsUnProcessed().map { list ->
dealGroups(list) dealGroups(list)
} }.flowOn(IO)
} }
} }
@@ -6,6 +6,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseActivity import io.legado.app.base.BaseActivity
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
@@ -126,7 +127,7 @@ class ReadRecordActivity : BaseActivity<ActivityReadRecordBinding>() {
} }
private fun initAllTime() { private fun initAllTime() {
launch { lifecycleScope.launch {
val allTime = withContext(IO) { val allTime = withContext(IO) {
appDb.readRecordDao.allTime appDb.readRecordDao.allTime
} }
@@ -135,7 +136,7 @@ class ReadRecordActivity : BaseActivity<ActivityReadRecordBinding>() {
} }
private fun initData(searchKey: String? = null) { private fun initData(searchKey: String? = null) {
launch { lifecycleScope.launch {
val readRecords = withContext(IO) { val readRecords = withContext(IO) {
appDb.readRecordDao.search(searchKey ?: "").let { records -> appDb.readRecordDao.search(searchKey ?: "").let { records ->
when (sortMode) { when (sortMode) {
@@ -181,7 +182,7 @@ class ReadRecordActivity : BaseActivity<ActivityReadRecordBinding>() {
binding.apply { binding.apply {
root.setOnClickListener { root.setOnClickListener {
val item = getItem(holder.layoutPosition) ?: return@setOnClickListener val item = getItem(holder.layoutPosition) ?: return@setOnClickListener
launch { lifecycleScope.launch {
val book = withContext(IO) { val book = withContext(IO) {
appDb.bookDao.findByName(item.bookName).firstOrNull() appDb.bookDao.findByName(item.bookName).firstOrNull()
} }
@@ -5,6 +5,7 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
@@ -16,13 +17,19 @@ import io.legado.app.lib.permission.Permissions
import io.legado.app.lib.permission.PermissionsCompat import io.legado.app.lib.permission.PermissionsCompat
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.file.HandleFileContract import io.legado.app.ui.file.HandleFileContract
import io.legado.app.utils.* import io.legado.app.utils.FileUtils
import io.legado.app.utils.checkWrite
import io.legado.app.utils.getFile
import io.legado.app.utils.isContentScheme
import io.legado.app.utils.readUri
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.startActivity
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@@ -147,7 +154,7 @@ class FileAssociationActivity :
} }
private fun importBook(treeUri: Uri, uri: Uri) { private fun importBook(treeUri: Uri, uri: Uri) {
launch { lifecycleScope.launch {
runCatching { runCatching {
withContext(IO) { withContext(IO) {
if (treeUri.isContentScheme()) { if (treeUri.isContentScheme()) {
@@ -10,6 +10,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.SeekBar import android.widget.SeekBar
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
@@ -195,7 +196,7 @@ class AudioPlayActivity :
viewModel.changeTo(source, book, toc) viewModel.changeTo(source, book, toc)
} else { } else {
AudioPlay.stop(this) AudioPlay.stop(this)
launch { lifecycleScope.launch {
withContext(IO) { withContext(IO) {
AudioPlay.book?.migrateTo(book, toc) AudioPlay.book?.migrateTo(book, toc)
book.removeType(BookType.updateError) book.removeType(BookType.updateError)
@@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.data.appDb import io.legado.app.data.appDb
@@ -33,7 +34,7 @@ class AllBookmarkActivity : VMBaseActivity<ActivityAllBookmarkBinding, AllBookma
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initView() initView()
launch { lifecycleScope.launch {
appDb.bookmarkDao.flowAll().collect { appDb.bookmarkDao.flowAll().collect {
adapter.setItems(it) adapter.setItems(it)
} }
@@ -7,6 +7,7 @@ import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import io.legado.app.R import io.legado.app.R
@@ -87,7 +88,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
groupId = intent.getLongExtra("groupId", -1) groupId = intent.getLongExtra("groupId", -1)
launch { lifecycleScope.launch {
binding.titleBar.subtitle = withContext(IO) { binding.titleBar.subtitle = withContext(IO) {
appDb.bookGroupDao.getByID(groupId)?.groupName appDb.bookGroupDao.getByID(groupId)?.groupName
?: getString(R.string.no_group) ?: getString(R.string.no_group)
@@ -185,7 +186,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
private fun initBookData() { private fun initBookData() {
booksFlowJob?.cancel() booksFlowJob?.cancel()
booksFlowJob = launch { booksFlowJob = lifecycleScope.launch {
appDb.bookDao.flowByGroup(groupId).map { books -> appDb.bookDao.flowByGroup(groupId).map { books ->
val booksDownload = books.filter { val booksDownload = books.filter {
!it.isAudio !it.isAudio
@@ -208,7 +209,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
private fun initGroupData() { private fun initGroupData() {
launch { lifecycleScope.launch {
appDb.bookGroupDao.flowAll().conflate().collect { appDb.bookGroupDao.flowAll().conflate().collect {
groupList.clear() groupList.clear()
groupList.addAll(it) groupList.addAll(it)
@@ -44,7 +44,6 @@ import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**
@@ -205,7 +204,7 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
} }
} }
lifecycleScope.launch { lifecycleScope.launch {
appDb.bookSourceDao.flowEnabledGroups().flowOn(IO).conflate().collect { appDb.bookSourceDao.flowEnabledGroups().conflate().collect {
groups.clear() groups.clear()
groups.addAll(it) groups.addAll(it)
upGroupMenu() upGroupMenu()
@@ -45,10 +45,8 @@ import io.legado.app.utils.startActivity
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -235,7 +233,7 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
} }
} }
lifecycleScope.launch { lifecycleScope.launch {
appDb.bookSourceDao.flowEnabledGroups().flowOn(IO).conflate().collect { appDb.bookSourceDao.flowEnabledGroups().conflate().collect {
groups.clear() groups.clear()
groups.addAll(it) groups.addAll(it)
upGroupMenu() upGroupMenu()
@@ -5,9 +5,11 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.addCallback
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
@@ -23,9 +25,11 @@ import io.legado.app.ui.file.HandleFileContract
import io.legado.app.ui.widget.SelectActionBar import io.legado.app.ui.widget.SelectActionBar
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File import java.io.File
/** /**
@@ -49,7 +53,12 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
searchView.queryHint = getString(R.string.screen) + "" + getString(R.string.local_book) searchView.queryHint = getString(R.string.screen) + "" + getString(R.string.local_book)
launch { onBackPressedDispatcher.addCallback(this) {
if (!goBackDir()) {
finish()
}
}
lifecycleScope.launch {
initView() initView()
initEvent() initEvent()
if (setBookStorage() && AppConfig.importBookPath.isNullOrBlank()) { if (setBookStorage() && AppConfig.importBookPath.isNullOrBlank()) {
@@ -129,7 +138,7 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
viewModel.dataFlowStart = { viewModel.dataFlowStart = {
initRootDoc() initRootDoc()
} }
launch { lifecycleScope.launch {
viewModel.dataFlow.conflate().collect { docs -> viewModel.dataFlow.conflate().collect { docs ->
adapter.setItems(docs) adapter.setItems(docs)
} }
@@ -235,9 +244,9 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
val lastDoc = viewModel.subDocs.lastOrNull() ?: doc val lastDoc = viewModel.subDocs.lastOrNull() ?: doc
binding.refreshProgressBar.isAutoLoading = true binding.refreshProgressBar.isAutoLoading = true
scanDocJob?.cancel() scanDocJob?.cancel()
scanDocJob = launch(IO) { scanDocJob = lifecycleScope.launch(IO) {
viewModel.scanDoc(lastDoc, true, this) { viewModel.scanDoc(lastDoc, true) {
launch { withContext(Main) {
binding.refreshProgressBar.isAutoLoading = false binding.refreshProgressBar.isAutoLoading = false
} }
} }
@@ -281,14 +290,6 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
viewModel.updateCallBackFlow(newText) viewModel.updateCallBackFlow(newText)
} }
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if (!goBackDir()) {
@Suppress("DEPRECATION")
super.onBackPressed()
}
}
override fun upCountView() { override fun upCountView() {
binding.selectActionBar.upCountView(adapter.selectedUris.size, adapter.checkableCount) binding.selectActionBar.upCountView(adapter.selectedUris.size, adapter.checkableCount)
} }
@@ -9,8 +9,11 @@ import io.legado.app.constant.AppPattern.archiveFileRegex
import io.legado.app.constant.AppPattern.bookFileRegex import io.legado.app.constant.AppPattern.bookFileRegex
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.utils.* import io.legado.app.utils.FileDoc
import kotlinx.coroutines.CoroutineScope import io.legado.app.utils.getPrefInt
import io.legado.app.utils.isContentScheme
import io.legado.app.utils.list
import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
@@ -20,7 +23,8 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import java.util.* import java.util.Collections
import kotlin.coroutines.coroutineContext
class ImportBookViewModel(application: Application) : BaseViewModel(application) { class ImportBookViewModel(application: Application) : BaseViewModel(application) {
var rootDoc: FileDoc? = null var rootDoc: FileDoc? = null
@@ -133,34 +137,35 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
} }
} }
fun scanDoc( suspend fun scanDoc(
fileDoc: FileDoc, fileDoc: FileDoc,
isRoot: Boolean, isRoot: Boolean,
scope: CoroutineScope, finally: (suspend () -> Unit)? = null
finally: (() -> Unit)? = null
) { ) {
if (isRoot) { if (isRoot) {
dataCallback?.clear() dataCallback?.clear()
} }
if (!scope.isActive) { if (!coroutineContext.isActive) {
finally?.invoke() finally?.invoke()
return return
} }
kotlin.runCatching { kotlin.runCatching {
val list = ArrayList<FileDoc>() val list = ArrayList<FileDoc>()
fileDoc.list()!!.forEach { docItem -> fileDoc.list()!!.forEach { docItem ->
if (!scope.isActive) { if (!coroutineContext.isActive) {
finally?.invoke() finally?.invoke()
return return
} }
if (docItem.isDir) { if (docItem.isDir) {
scanDoc(docItem, false, scope) scanDoc(docItem, false)
} else if (docItem.name.matches(bookFileRegex) || docItem.name.matches(archiveFileRegex) } else if (docItem.name.matches(bookFileRegex) || docItem.name.matches(
archiveFileRegex
)
) { ) {
list.add(docItem) list.add(docItem)
} }
} }
if (!scope.isActive) { if (!coroutineContext.isActive) {
finally?.invoke() finally?.invoke()
return return
} }
@@ -6,8 +6,10 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.SubMenu import android.view.SubMenu
import androidx.activity.addCallback
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.data.appDb import io.legado.app.data.appDb
@@ -43,7 +45,12 @@ class RemoteBookActivity : BaseImportBookActivity<RemoteBookViewModel>(),
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
searchView.queryHint = getString(R.string.screen) + "" + getString(R.string.remote_book) searchView.queryHint = getString(R.string.screen) + "" + getString(R.string.remote_book)
launch { onBackPressedDispatcher.addCallback(this) {
if (!goBackDir()) {
finish()
}
}
lifecycleScope.launch {
if (!setBookStorage()) { if (!setBookStorage()) {
finish() finish()
return@launch return@launch
@@ -152,14 +159,6 @@ class RemoteBookActivity : BaseImportBookActivity<RemoteBookViewModel>(),
} }
} }
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if (!goBackDir()) {
@Suppress("DEPRECATION")
super.onBackPressed()
}
}
private fun goBackDir(): Boolean { private fun goBackDir(): Boolean {
if (viewModel.dirList.isEmpty()) { if (viewModel.dirList.isEmpty()) {
return false return false
@@ -10,6 +10,7 @@ import android.widget.CheckBox
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Theme import io.legado.app.constant.Theme
@@ -62,7 +63,7 @@ class BookInfoActivity :
private val tocActivityResult = registerForActivityResult(TocActivityResult()) { private val tocActivityResult = registerForActivityResult(TocActivityResult()) {
it?.let { it?.let {
viewModel.getBook(false)?.let { book -> viewModel.getBook(false)?.let { book ->
launch { lifecycleScope.launch {
withContext(IO) { withContext(IO) {
book.durChapterIndex = it.first book.durChapterIndex = it.first
book.durChapterPos = it.second book.durChapterPos = it.second
@@ -247,7 +248,7 @@ class BookInfoActivity :
book: Book, book: Book,
bookWebDav: RemoteBookWebDav? = AppWebDav.defaultBookWebDav bookWebDav: RemoteBookWebDav? = AppWebDav.defaultBookWebDav
) { ) {
launch { lifecycleScope.launch {
waitDialog.setText("上传中.....") waitDialog.setText("上传中.....")
waitDialog.show() waitDialog.show()
try { try {
@@ -431,13 +432,14 @@ class BookInfoActivity :
} }
private fun setSourceVariable() { private fun setSourceVariable() {
launch { lifecycleScope.launch {
val source = viewModel.bookSource val source = viewModel.bookSource
if (source == null) { if (source == null) {
toastOnUi("书源不存在") toastOnUi("书源不存在")
return@launch return@launch
} }
val comment = source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") val comment =
source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取")
val variable = withContext(IO) { source.getVariable() } val variable = withContext(IO) { source.getVariable() }
showDialogFragment( showDialogFragment(
VariableDialog( VariableDialog(
@@ -451,7 +453,7 @@ class BookInfoActivity :
} }
private fun setBookVariable() { private fun setBookVariable() {
launch { lifecycleScope.launch {
val source = viewModel.bookSource val source = viewModel.bookSource
if (source == null) { if (source == null) {
toastOnUi("书源不存在") toastOnUi("书源不存在")
@@ -11,6 +11,7 @@ import android.widget.LinearLayout
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
@@ -72,7 +73,7 @@ class BookshelfManageActivity :
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.groupId = intent.getLongExtra("groupId", -1) viewModel.groupId = intent.getLongExtra("groupId", -1)
launch { lifecycleScope.launch {
viewModel.groupName = withContext(IO) { viewModel.groupName = withContext(IO) {
appDb.bookGroupDao.getByID(viewModel.groupId)?.groupName appDb.bookGroupDao.getByID(viewModel.groupId)?.groupName
?: getString(R.string.no_group) ?: getString(R.string.no_group)
@@ -184,7 +185,7 @@ class BookshelfManageActivity :
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
private fun initGroupData() { private fun initGroupData() {
launch { lifecycleScope.launch {
appDb.bookGroupDao.flowAll().conflate().collect { appDb.bookGroupDao.flowAll().conflate().collect {
groupList.clear() groupList.clear()
groupList.addAll(it) groupList.addAll(it)
@@ -196,7 +197,7 @@ class BookshelfManageActivity :
private fun upBookDataByGroupId() { private fun upBookDataByGroupId() {
booksFlowJob?.cancel() booksFlowJob?.cancel()
booksFlowJob = launch { booksFlowJob = lifecycleScope.launch {
val bookSort = AppConfig.getBookSortByGroupId(viewModel.groupId) val bookSort = AppConfig.getBookSortByGroupId(viewModel.groupId)
appDb.bookDao.flowByGroup(viewModel.groupId).map { list -> appDb.bookDao.flowByGroup(viewModel.groupId).map { list ->
when (bookSort) { when (bookSort) {
@@ -13,6 +13,7 @@ import androidx.appcompat.widget.PopupMenu
import androidx.core.view.get import androidx.core.view.get
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.size import androidx.core.view.size
import androidx.lifecycle.lifecycleScope
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
import io.legado.app.BuildConfig import io.legado.app.BuildConfig
import io.legado.app.R import io.legado.app.R
@@ -323,7 +324,7 @@ class ReadBookActivity : BaseReadBookActivity(),
} }
} }
} }
launch { lifecycleScope.launch {
menu.findItem(R.id.menu_get_progress)?.isVisible = withContext(IO) { menu.findItem(R.id.menu_get_progress)?.isVisible = withContext(IO) {
AppWebDav.isOk AppWebDav.isOk
} }
@@ -344,7 +345,7 @@ class ReadBookActivity : BaseReadBookActivity(),
} }
} }
R.id.menu_chapter_change_source -> launch { R.id.menu_chapter_change_source -> lifecycleScope.launch {
val book = ReadBook.book ?: return@launch val book = ReadBook.book ?: return@launch
val chapter = val chapter =
appDb.bookChapterDao.getChapter(book.bookUrl, ReadBook.durChapterIndex) appDb.bookChapterDao.getChapter(book.bookUrl, ReadBook.durChapterIndex)
@@ -769,7 +770,7 @@ class ReadBookActivity : BaseReadBookActivity(),
} }
override fun upMenuView() { override fun upMenuView() {
launch { lifecycleScope.launch {
upMenu() upMenu()
binding.readMenu.upBookView() binding.readMenu.upBookView()
} }
@@ -799,7 +800,7 @@ class ReadBookActivity : BaseReadBookActivity(),
resetPageOffset: Boolean, resetPageOffset: Boolean,
success: (() -> Unit)? success: (() -> Unit)?
) { ) {
launch { lifecycleScope.launch {
autoPageProgress = 0 autoPageProgress = 0
binding.readView.upContent(relativePosition, resetPageOffset) binding.readView.upContent(relativePosition, resetPageOffset)
upSeekBarProgress() upSeekBarProgress()
@@ -809,7 +810,7 @@ class ReadBookActivity : BaseReadBookActivity(),
} }
override fun upPageAnim() { override fun upPageAnim() {
launch { lifecycleScope.launch {
binding.readView.upPageAnim() binding.readView.upPageAnim()
} }
} }
@@ -822,7 +823,7 @@ class ReadBookActivity : BaseReadBookActivity(),
* 页面改变 * 页面改变
*/ */
override fun pageChanged() { override fun pageChanged() {
launch { lifecycleScope.launch {
autoPageProgress = 0 autoPageProgress = 0
upSeekBarProgress() upSeekBarProgress()
startBackupJob() startBackupJob()
@@ -855,7 +856,7 @@ class ReadBookActivity : BaseReadBookActivity(),
viewModel.changeTo(book, toc) viewModel.changeTo(book, toc)
} else { } else {
ReadAloud.stop(this) ReadAloud.stop(this)
launch { lifecycleScope.launch {
withContext(IO) { withContext(IO) {
ReadBook.book?.migrateTo(book, toc) ReadBook.book?.migrateTo(book, toc)
book.removeType(BookType.updateError) book.removeType(BookType.updateError)
@@ -925,7 +926,7 @@ class ReadBookActivity : BaseReadBookActivity(),
private fun autoPagePlus() { private fun autoPagePlus() {
autoPageJob?.cancel() autoPageJob?.cancel()
autoPageJob = launch { autoPageJob = lifecycleScope.launch {
while (isActive) { while (isActive) {
var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height
var scrollOffset = 1 var scrollOffset = 1
@@ -1307,7 +1308,7 @@ class ReadBookActivity : BaseReadBookActivity(),
private fun startBackupJob() { private fun startBackupJob() {
backupJob?.cancel() backupJob?.cancel()
backupJob = launch(IO) { backupJob = lifecycleScope.launch(IO) {
delay(300000) delay(300000)
ReadBook.book?.let { ReadBook.book?.let {
AppWebDav.uploadBookProgress(it) AppWebDav.uploadBookProgress(it)
@@ -1389,7 +1390,7 @@ class ReadBookActivity : BaseReadBookActivity(),
} }
} }
observeEventSticky<Int>(EventBus.TTS_PROGRESS) { chapterStart -> observeEventSticky<Int>(EventBus.TTS_PROGRESS) { chapterStart ->
launch(IO) { lifecycleScope.launch(IO) {
if (BaseReadAloudService.isPlay()) { if (BaseReadAloudService.isPlay()) {
ReadBook.curTextChapter?.let { textChapter -> ReadBook.curTextChapter?.let { textChapter ->
val pageIndex = ReadBook.durPageIndex val pageIndex = ReadBook.durPageIndex
@@ -1432,7 +1433,7 @@ class ReadBookActivity : BaseReadBookActivity(),
*/ */
override fun screenOffTimerStart() { override fun screenOffTimerStart() {
keepScreenJon?.cancel() keepScreenJon?.cancel()
keepScreenJon = launch { keepScreenJon = lifecycleScope.launch {
if (screenTimeOut < 0) { if (screenTimeOut < 0) {
keepScreenOn(true) keepScreenOn(true)
return@launch return@launch
@@ -11,6 +11,7 @@ import android.widget.TextView
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager import com.google.android.flexbox.FlexboxLayoutManager
@@ -22,16 +23,28 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.SearchKeyword import io.legado.app.data.entities.SearchKeyword
import io.legado.app.databinding.ActivityBookSearchBinding import io.legado.app.databinding.ActivityBookSearchBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.* import io.legado.app.lib.theme.Selector
import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor
import io.legado.app.lib.theme.primaryTextColor
import io.legado.app.ui.about.AppLogDialog import io.legado.app.ui.about.AppLogDialog
import io.legado.app.ui.book.info.BookInfoActivity import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.source.manage.BookSourceActivity import io.legado.app.ui.book.source.manage.BookSourceActivity
import io.legado.app.utils.* import io.legado.app.utils.ColorUtils
import io.legado.app.utils.applyTint
import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.gone
import io.legado.app.utils.invisible
import io.legado.app.utils.putPrefBoolean
import io.legado.app.utils.setEdgeEffectColor
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.startActivity
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.init.appCtx import splitties.init.appCtx
@@ -67,7 +80,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
private var isManualStopSearch = false private var isManualStopSearch = false
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = searchFinish@{ isEmpty -> private val searchFinishCallback: (isEmpty: Boolean) -> Unit = searchFinish@{ isEmpty ->
if (!isEmpty || viewModel.searchScope.isAll()) return@searchFinish if (!isEmpty || viewModel.searchScope.isAll()) return@searchFinish
launch { lifecycleScope.launch {
alert("搜索结果为空") { alert("搜索结果为空") {
val precisionSearch = appCtx.getPrefBoolean(PreferKey.precisionSearch) val precisionSearch = appCtx.getPrefBoolean(PreferKey.precisionSearch)
if (precisionSearch) { if (precisionSearch) {
@@ -280,7 +293,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
viewModel.searchBookLiveData.observe(this) { viewModel.searchBookLiveData.observe(this) {
adapter.setItems(it) adapter.setItems(it)
} }
launch(IO) { lifecycleScope.launch(IO) {
appDb.bookSourceDao.flowEnabledGroups().collect { appDb.bookSourceDao.flowEnabledGroups().collect {
groups = it groups = it
} }
@@ -337,7 +350,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
*/ */
private fun upHistory(key: String? = null) { private fun upHistory(key: String? = null) {
booksFlowJob?.cancel() booksFlowJob?.cancel()
booksFlowJob = launch { booksFlowJob = lifecycleScope.launch {
if (key.isNullOrBlank()) { if (key.isNullOrBlank()) {
binding.tvBookShow.gone() binding.tvBookShow.gone()
binding.rvBookshelfSearch.gone() binding.rvBookshelfSearch.gone()
@@ -355,7 +368,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
} }
} }
historyFlowJob?.cancel() historyFlowJob?.cancel()
historyFlowJob = launch { historyFlowJob = lifecycleScope.launch {
when { when {
key.isNullOrBlank() -> appDb.searchKeywordDao.flowByTime() key.isNullOrBlank() -> appDb.searchKeywordDao.flowByTime()
else -> appDb.searchKeywordDao.flowSearch(key) else -> appDb.searchKeywordDao.flowSearch(key)
@@ -425,7 +438,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
* 点击历史关键字 * 点击历史关键字
*/ */
override fun searchHistory(key: String) { override fun searchHistory(key: String) {
launch { lifecycleScope.launch {
when { when {
searchView.query.toString() == key -> { searchView.query.toString() == key -> {
searchView.setQuery(key, true) searchView.setQuery(key, true)
@@ -10,6 +10,7 @@ import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.view.allViews import androidx.core.view.allViews
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
@@ -172,7 +173,7 @@ class SearchContentActivity :
} }
private fun initCacheFileNames(book: Book) { private fun initCacheFileNames(book: Book) {
initJob = async { initJob = lifecycleScope.async {
withContext(IO) { withContext(IO) {
viewModel.cacheChapterNames.addAll(BookHelp.getChapterFiles(book)) viewModel.cacheChapterNames.addAll(BookHelp.getChapterFiles(book))
} }
@@ -202,7 +203,7 @@ class SearchContentActivity :
viewModel.lastQuery = query viewModel.lastQuery = query
binding.refreshProgressBar.isAutoLoading = true binding.refreshProgressBar.isAutoLoading = true
binding.fbStop.visible() binding.fbStop.visible()
searchJob = launch(IO) { searchJob = lifecycleScope.launch(IO) {
initJob?.await() initJob?.await()
kotlin.runCatching { kotlin.runCatching {
appDb.bookChapterDao.getChapterList(viewModel.bookUrl).forEach { bookChapter -> appDb.bookChapterDao.getChapterList(viewModel.bookUrl).forEach { bookChapter ->
@@ -7,6 +7,7 @@ import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.databinding.ActivitySourceDebugBinding import io.legado.app.databinding.ActivitySourceDebugBinding
@@ -47,7 +48,7 @@ class BookSourceDebugActivity : VMBaseActivity<ActivitySourceDebugBinding, BookS
initHelpView() initHelpView()
} }
viewModel.observe { state, msg -> viewModel.observe { state, msg ->
launch { lifecycleScope.launch {
adapter.addItem(msg) adapter.addItem(msg)
if (state == -1 || state == 1000) { if (state == -1 || state == 1000) {
binding.rotateLoading.gone() binding.rotateLoading.gone()
@@ -113,7 +114,7 @@ class BookSourceDebugActivity : VMBaseActivity<ActivitySourceDebugBinding, BookS
binding.textContent.onClick { binding.textContent.onClick {
prefixAutoComplete("--") prefixAutoComplete("--")
} }
launch { lifecycleScope.launch {
val exploreKinds = viewModel.bookSource?.exploreKinds()?.filter { val exploreKinds = viewModel.bookSource?.exploreKinds()?.filter {
!it.url.isNullOrBlank() !it.url.isNullOrBlank()
} }
@@ -6,6 +6,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.EditText import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
@@ -86,7 +87,7 @@ class BookSourceEditActivity :
} }
private val softKeyboardTool by lazy { private val softKeyboardTool by lazy {
KeyboardToolPop(this, this, binding.root, this) KeyboardToolPop(this, lifecycleScope, binding.root, this)
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
@@ -556,7 +557,7 @@ class BookSourceEditActivity :
} }
private fun alertGroups() { private fun alertGroups() {
launch { lifecycleScope.launch {
val groups = withContext(IO) { val groups = withContext(IO) {
appDb.bookSourceDao.allGroups() appDb.bookSourceDao.allGroups()
} }
@@ -628,7 +629,7 @@ class BookSourceEditActivity :
private fun setSourceVariable() { private fun setSourceVariable() {
viewModel.save(getSource()) { source -> viewModel.save(getSource()) { source ->
launch { lifecycleScope.launch {
val comment = val comment =
source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取")
val variable = withContext(IO) { source.getVariable() } val variable = withContext(IO) { source.getVariable() }
@@ -9,6 +9,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import io.legado.app.R import io.legado.app.R
@@ -249,7 +250,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private fun upBookSource(searchKey: String? = null) { private fun upBookSource(searchKey: String? = null) {
this.searchKey = searchKey this.searchKey = searchKey
sourceFlowJob?.cancel() sourceFlowJob?.cancel()
sourceFlowJob = launch { sourceFlowJob = lifecycleScope.launch {
when { when {
searchKey.isNullOrEmpty() -> { searchKey.isNullOrEmpty() -> {
appDb.bookSourceDao.flowAll() appDb.bookSourceDao.flowAll()
@@ -337,8 +338,8 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
} }
private fun initLiveDataGroup() { private fun initLiveDataGroup() {
launch { lifecycleScope.launch {
appDb.bookSourceDao.flowGroups().flowOn(IO).conflate().collect { appDb.bookSourceDao.flowGroups().conflate().collect {
groups.clear() groups.clear()
groups.addAll(it) groups.addAll(it)
upGroupMenu() upGroupMenu()
@@ -563,7 +564,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
} }
private fun checkMessageRefreshJob(firstItem: Int, lastItem: Int): Job { private fun checkMessageRefreshJob(firstItem: Int, lastItem: Int): Job {
return async(start = CoroutineStart.LAZY) { return lifecycleScope.async(start = CoroutineStart.LAZY) {
flow { flow {
while (true) { while (true) {
emit(Debug.isChecking) emit(Debug.isChecking)
@@ -26,8 +26,6 @@ import io.legado.app.utils.applyTint
import io.legado.app.utils.requestInputMethod import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.setLayout import io.legado.app.utils.setLayout
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -58,7 +56,7 @@ class GroupManageDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
private fun initData() { private fun initData() {
lifecycleScope.launch { lifecycleScope.launch {
appDb.bookSourceDao.flowGroups().flowOn(IO).collect { appDb.bookSourceDao.flowGroups().collect {
adapter.setItems(it) adapter.setItems(it)
} }
} }
@@ -6,6 +6,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
@@ -101,7 +102,7 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
} }
private fun initData() { private fun initData() {
launch { lifecycleScope.launch {
appDb.txtTocRuleDao.observeAll().conflate().collect { tocRules -> appDb.txtTocRuleDao.observeAll().conflate().collect { tocRules ->
adapter.setItems(tocRules, adapter.diffItemCallBack) adapter.setItems(tocRules, adapter.diffItemCallBack)
upCountView() upCountView()
@@ -6,6 +6,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
@@ -110,7 +111,7 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
} }
private fun observeDictRuleData() { private fun observeDictRuleData() {
launch { lifecycleScope.launch {
appDb.dictRuleDao.flowAll().collect { appDb.dictRuleDao.flowAll().collect {
adapter.setItems(it, adapter.diffItemCallBack) adapter.setItems(it, adapter.diffItemCallBack)
} }
@@ -14,6 +14,7 @@ import androidx.core.view.postDelayed
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.lifecycle.lifecycleScope
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import io.legado.app.BuildConfig import io.legado.app.BuildConfig
@@ -126,7 +127,7 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
override fun onPostCreate(savedInstanceState: Bundle?) { override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState) super.onPostCreate(savedInstanceState)
launch { lifecycleScope.launch {
//隐私协议 //隐私协议
if (!privacyPolicy()) return@launch if (!privacyPolicy()) return@launch
//版本更新 //版本更新
@@ -269,7 +270,7 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
* 备份同步 * 备份同步
*/ */
private fun backupSync() { private fun backupSync() {
launch { lifecycleScope.launch {
val lastBackupFile = val lastBackupFile =
withContext(IO) { AppWebDav.lastBackUp().getOrNull() } ?: return@launch withContext(IO) { AppWebDav.lastBackUp().getOrNull() } ?: return@launch
if (lastBackupFile.lastModify - LocalConfig.lastBackup > DateUtils.MINUTE_IN_MILLIS) { if (lastBackupFile.lastModify - LocalConfig.lastBackup > DateUtils.MINUTE_IN_MILLIS) {
@@ -130,7 +130,7 @@ class ExploreFragment() : VMBaseFragment<ExploreViewModel>(R.layout.fragment_exp
private fun initGroupData() { private fun initGroupData() {
lifecycleScope.launch { lifecycleScope.launch {
appDb.bookSourceDao.flowExploreGroups().flowOn(IO).conflate().collect { appDb.bookSourceDao.flowExploreGroups().conflate().collect {
groups.clear() groups.clear()
groups.addAll(it) groups.addAll(it)
upGroupsMenu() upGroupsMenu()
@@ -12,6 +12,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
@@ -189,14 +190,16 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
private fun observeReplaceRuleData(searchKey: String? = null) { private fun observeReplaceRuleData(searchKey: String? = null) {
dataInit = false dataInit = false
replaceRuleFlowJob?.cancel() replaceRuleFlowJob?.cancel()
replaceRuleFlowJob = launch { replaceRuleFlowJob = lifecycleScope.launch {
when { when {
searchKey.isNullOrEmpty() -> { searchKey.isNullOrEmpty() -> {
appDb.replaceRuleDao.flowAll() appDb.replaceRuleDao.flowAll()
} }
searchKey == getString(R.string.no_group) -> { searchKey == getString(R.string.no_group) -> {
appDb.replaceRuleDao.flowNoGroup() appDb.replaceRuleDao.flowNoGroup()
} }
searchKey.startsWith("group:") -> { searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:") val key = searchKey.substringAfter("group:")
appDb.replaceRuleDao.flowGroupSearch("%$key%") appDb.replaceRuleDao.flowGroupSearch("%$key%")
@@ -218,7 +221,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
} }
private fun observeGroupData() { private fun observeGroupData() {
launch { lifecycleScope.launch {
appDb.replaceRuleDao.flowGroups().collect { appDb.replaceRuleDao.flowGroups().collect {
groups.clear() groups.clear()
groups.addAll(it) groups.addAll(it)
@@ -7,6 +7,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.EditText import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
@@ -49,7 +50,7 @@ class ReplaceEditActivity :
override val viewModel by viewModels<ReplaceEditViewModel>() override val viewModel by viewModels<ReplaceEditViewModel>()
private val softKeyboardTool by lazy { private val softKeyboardTool by lazy {
KeyboardToolPop(this, this, binding.root, this) KeyboardToolPop(this, lifecycleScope, binding.root, this)
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
@@ -9,6 +9,7 @@ import android.view.ViewGroup
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentStatePagerAdapter import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.databinding.ActivityRssArtivlesBinding import io.legado.app.databinding.ActivityRssArtivlesBinding
@@ -91,7 +92,7 @@ class RssSortActivity : VMBaseActivity<ActivityRssArtivlesBinding, RssSortViewMo
} }
private fun upFragments() { private fun upFragments() {
launch { lifecycleScope.launch {
viewModel.rssSource?.sortUrls()?.let { viewModel.rssSource?.sortUrls()?.let {
sortList.clear() sortList.clear()
sortList.addAll(it) sortList.addAll(it)
@@ -106,13 +107,14 @@ class RssSortActivity : VMBaseActivity<ActivityRssArtivlesBinding, RssSortViewMo
} }
private fun setSourceVariable() { private fun setSourceVariable() {
launch { lifecycleScope.launch {
val source = viewModel.rssSource val source = viewModel.rssSource
if (source == null) { if (source == null) {
toastOnUi("源不存在") toastOnUi("源不存在")
return@launch return@launch
} }
val comment = source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") val comment =
source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取")
val variable = withContext(Dispatchers.IO) { source.getVariable() } val variable = withContext(Dispatchers.IO) { source.getVariable() }
showDialogFragment( showDialogFragment(
VariableDialog( VariableDialog(
@@ -1,6 +1,7 @@
package io.legado.app.ui.rss.favorites package io.legado.app.ui.rss.favorites
import android.os.Bundle import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.base.BaseActivity import io.legado.app.base.BaseActivity
import io.legado.app.data.appDb import io.legado.app.data.appDb
@@ -36,7 +37,7 @@ class RssFavoritesActivity : BaseActivity<ActivityRssFavoritesBinding>(),
} }
private fun initData() { private fun initData() {
launch { lifecycleScope.launch {
appDb.rssStarDao.liveAll().conflate().collect { appDb.rssStarDao.liveAll().conflate().collect {
adapter.setItems(it) adapter.setItems(it)
} }
@@ -11,6 +11,7 @@ import android.webkit.*
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.view.size import androidx.core.view.size
import androidx.lifecycle.lifecycleScope
import com.script.rhino.RhinoScriptEngine import com.script.rhino.RhinoScriptEngine
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
@@ -263,7 +264,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
} }
private fun upTtsMenu(isPlaying: Boolean) { private fun upTtsMenu(isPlaying: Boolean) {
launch { lifecycleScope.launch {
if (isPlaying) { if (isPlaying) {
ttsMenuItem?.setIcon(R.drawable.ic_stop_black_24dp) ttsMenuItem?.setIcon(R.drawable.ic_stop_black_24dp)
ttsMenuItem?.setTitle(R.string.aloud_stop) ttsMenuItem?.setTitle(R.string.aloud_stop)
@@ -5,6 +5,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.SearchView import android.widget.SearchView
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.databinding.ActivitySourceDebugBinding import io.legado.app.databinding.ActivitySourceDebugBinding
@@ -30,7 +31,7 @@ class RssSourceDebugActivity : VMBaseActivity<ActivitySourceDebugBinding, RssSou
initRecyclerView() initRecyclerView()
initSearchView() initSearchView()
viewModel.observe { state, msg -> viewModel.observe { state, msg ->
launch { lifecycleScope.launch {
adapter.addItem(msg) adapter.addItem(msg)
if (state == -1 || state == 1000) { if (state == -1 || state == 1000) {
binding.rotateLoading.gone() binding.rotateLoading.gone()
@@ -6,6 +6,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.EditText import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import io.legado.app.R import io.legado.app.R
@@ -50,7 +51,7 @@ class RssSourceEditActivity :
override val binding by viewBinding(ActivityRssSourceEditBinding::inflate) override val binding by viewBinding(ActivityRssSourceEditBinding::inflate)
override val viewModel by viewModels<RssSourceEditViewModel>() override val viewModel by viewModels<RssSourceEditViewModel>()
private val softKeyboardTool by lazy { private val softKeyboardTool by lazy {
KeyboardToolPop(this, this, binding.root, this) KeyboardToolPop(this, lifecycleScope, binding.root, this)
} }
private val adapter by lazy { RssSourceEditAdapter() } private val adapter by lazy { RssSourceEditAdapter() }
private val sourceEntities: ArrayList<EditEntity> = ArrayList() private val sourceEntities: ArrayList<EditEntity> = ArrayList()
@@ -328,7 +329,7 @@ class RssSourceEditActivity :
private fun setSourceVariable() { private fun setSourceVariable() {
viewModel.save(getRssSource()) { source -> viewModel.save(getRssSource()) { source ->
launch { lifecycleScope.launch {
val comment = val comment =
source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取")
val variable = withContext(Dispatchers.IO) { source.getVariable() } val variable = withContext(Dispatchers.IO) { source.getVariable() }
@@ -10,6 +10,7 @@ import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
@@ -219,7 +220,7 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
} }
private fun initGroupFlow() { private fun initGroupFlow() {
launch { lifecycleScope.launch {
appDb.rssSourceDao.flowGroups().conflate().collect { appDb.rssSourceDao.flowGroups().conflate().collect {
groups.clear() groups.clear()
groups.addAll(it) groups.addAll(it)
@@ -302,14 +303,16 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
private fun upSourceFlow(searchKey: String? = null) { private fun upSourceFlow(searchKey: String? = null) {
sourceFlowJob?.cancel() sourceFlowJob?.cancel()
sourceFlowJob = launch { sourceFlowJob = lifecycleScope.launch {
when { when {
searchKey.isNullOrBlank() -> { searchKey.isNullOrBlank() -> {
appDb.rssSourceDao.flowAll() appDb.rssSourceDao.flowAll()
} }
searchKey == getString(R.string.enabled) -> { searchKey == getString(R.string.enabled) -> {
appDb.rssSourceDao.flowEnabled() appDb.rssSourceDao.flowEnabled()
} }
searchKey == getString(R.string.disabled) -> { searchKey == getString(R.string.disabled) -> {
appDb.rssSourceDao.flowDisabled() appDb.rssSourceDao.flowDisabled()
} }
@@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseActivity import io.legado.app.base.BaseActivity
@@ -61,7 +62,7 @@ class RuleSubActivity : BaseActivity<ActivityRuleSubBinding>(),
} }
private fun initData() { private fun initData() {
launch { lifecycleScope.launch {
appDb.ruleSubDao.flowAll().conflate().collect { appDb.ruleSubDao.flowAll().conflate().collect {
binding.tvEmptyMsg.isGone = it.isNotEmpty() binding.tvEmptyMsg.isGone = it.isNotEmpty()
adapter.setItems(it) adapter.setItems(it)
@@ -92,7 +93,7 @@ class RuleSubActivity : BaseActivity<ActivityRuleSubBinding>(),
} }
customView { alertBinding.root } customView { alertBinding.root }
okButton { okButton {
launch { lifecycleScope.launch {
ruleSub.type = alertBinding.spType.selectedItemPosition ruleSub.type = alertBinding.spType.selectedItemPosition
ruleSub.name = alertBinding.etName.text?.toString() ?: "" ruleSub.name = alertBinding.etName.text?.toString() ?: ""
ruleSub.url = alertBinding.etUrl.text?.toString() ?: "" ruleSub.url = alertBinding.etUrl.text?.toString() ?: ""
@@ -113,19 +114,19 @@ class RuleSubActivity : BaseActivity<ActivityRuleSubBinding>(),
} }
override fun delSubscription(ruleSub: RuleSub) { override fun delSubscription(ruleSub: RuleSub) {
launch(IO) { lifecycleScope.launch(IO) {
appDb.ruleSubDao.delete(ruleSub) appDb.ruleSubDao.delete(ruleSub)
} }
} }
override fun updateSourceSub(vararg ruleSub: RuleSub) { override fun updateSourceSub(vararg ruleSub: RuleSub) {
launch(IO) { lifecycleScope.launch(IO) {
appDb.ruleSubDao.update(*ruleSub) appDb.ruleSubDao.update(*ruleSub)
} }
} }
override fun upOrder() { override fun upOrder() {
launch(IO) { lifecycleScope.launch(IO) {
val sourceSubs = appDb.ruleSubDao.all val sourceSubs = appDb.ruleSubDao.all
for ((index: Int, ruleSub: RuleSub) in sourceSubs.withIndex()) { for ((index: Int, ruleSub: RuleSub) in sourceSubs.withIndex()) {
ruleSub.customOrder = index + 1 ruleSub.customOrder = index + 1