diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index b6d07a1af..3781de4b2 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -25,9 +25,6 @@ import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.TitleBar import io.legado.app.utils.* -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.cancel abstract class BaseActivity( @@ -36,7 +33,7 @@ abstract class BaseActivity( private val toolBarTheme: Theme = Theme.Auto, private val transparent: Boolean = false, private val imageBg: Boolean = true -) : AppCompatActivity(), CoroutineScope by MainScope() { +) : AppCompatActivity() { protected abstract val binding: VB @@ -97,11 +94,6 @@ abstract class BaseActivity( setupSystemBar() } - override fun onDestroy() { - super.onDestroy() - cancel() - } - abstract fun onActivityCreated(savedInstanceState: Bundle?) final override fun onCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index f6cb736c6..27c2fd6b0 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -6,7 +6,9 @@ import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSourcePart import io.legado.app.utils.cnCompare import io.legado.app.utils.splitNotBlank +import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @Dao @@ -293,18 +295,18 @@ interface BookSourceDao { fun flowGroups(): Flow> { return flowGroupsUnProcessed().map { list -> dealGroups(list) - } + }.flowOn(IO) } fun flowExploreGroups(): Flow> { return flowExploreGroupsUnProcessed().map { list -> dealGroups(list) - } + }.flowOn(IO) } fun flowEnabledGroups(): Flow> { return flowEnabledGroupsUnProcessed().map { list -> dealGroups(list) - } + }.flowOn(IO) } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt index a73b7d2ba..e5bd2eef5 100644 --- a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt @@ -6,6 +6,7 @@ import android.view.Menu import android.view.MenuItem import android.view.ViewGroup import androidx.appcompat.widget.SearchView +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.BaseActivity import io.legado.app.base.adapter.ItemViewHolder @@ -126,7 +127,7 @@ class ReadRecordActivity : BaseActivity() { } private fun initAllTime() { - launch { + lifecycleScope.launch { val allTime = withContext(IO) { appDb.readRecordDao.allTime } @@ -135,7 +136,7 @@ class ReadRecordActivity : BaseActivity() { } private fun initData(searchKey: String? = null) { - launch { + lifecycleScope.launch { val readRecords = withContext(IO) { appDb.readRecordDao.search(searchKey ?: "").let { records -> when (sortMode) { @@ -181,7 +182,7 @@ class ReadRecordActivity : BaseActivity() { binding.apply { root.setOnClickListener { val item = getItem(holder.layoutPosition) ?: return@setOnClickListener - launch { + lifecycleScope.launch { val book = withContext(IO) { appDb.bookDao.findByName(item.bookName).firstOrNull() } diff --git a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt index b192c4ecc..ca04d0960 100644 --- a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt @@ -5,6 +5,7 @@ import android.os.Build import android.os.Bundle import androidx.activity.viewModels import androidx.documentfile.provider.DocumentFile +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity 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.ui.book.read.ReadBookActivity 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 kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import splitties.init.appCtx - import java.io.File import java.io.FileOutputStream @@ -147,7 +154,7 @@ class FileAssociationActivity : } private fun importBook(treeUri: Uri, uri: Uri) { - launch { + lifecycleScope.launch { runCatching { withContext(IO) { if (treeUri.isContentScheme()) { diff --git a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt index 2d252e74a..49cf4a452 100644 --- a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt @@ -10,6 +10,7 @@ import android.view.Menu import android.view.MenuItem import android.widget.SeekBar import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.BookType @@ -195,7 +196,7 @@ class AudioPlayActivity : viewModel.changeTo(source, book, toc) } else { AudioPlay.stop(this) - launch { + lifecycleScope.launch { withContext(IO) { AudioPlay.book?.migrateTo(book, toc) book.removeType(BookType.updateError) diff --git a/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkActivity.kt b/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkActivity.kt index 7d54305b8..d54c17706 100644 --- a/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkActivity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.data.appDb @@ -33,7 +34,7 @@ class AllBookmarkActivity : VMBaseActivity() override fun onActivityCreated(savedInstanceState: Bundle?) { groupId = intent.getLongExtra("groupId", -1) - launch { + lifecycleScope.launch { binding.titleBar.subtitle = withContext(IO) { appDb.bookGroupDao.getByID(groupId)?.groupName ?: getString(R.string.no_group) @@ -185,7 +186,7 @@ class CacheActivity : VMBaseActivity() private fun initBookData() { booksFlowJob?.cancel() - booksFlowJob = launch { + booksFlowJob = lifecycleScope.launch { appDb.bookDao.flowByGroup(groupId).map { books -> val booksDownload = books.filter { !it.isAudio @@ -208,7 +209,7 @@ class CacheActivity : VMBaseActivity() @SuppressLint("NotifyDataSetChanged") private fun initGroupData() { - launch { + lifecycleScope.launch { appDb.bookGroupDao.flowAll().conflate().collect { groupList.clear() groupList.addAll(it) diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt index 73a207284..31779a737 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt @@ -44,7 +44,6 @@ import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.delay import kotlinx.coroutines.flow.conflate -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch /** @@ -205,7 +204,7 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_ } } lifecycleScope.launch { - appDb.bookSourceDao.flowEnabledGroups().flowOn(IO).conflate().collect { + appDb.bookSourceDao.flowEnabledGroups().conflate().collect { groups.clear() groups.addAll(it) upGroupMenu() diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt index df9042fe5..cf1b747d5 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt @@ -45,10 +45,8 @@ import io.legado.app.utils.startActivity import io.legado.app.utils.toastOnUi import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.visible -import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.delay import kotlinx.coroutines.flow.conflate -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch @@ -235,7 +233,7 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c } } lifecycleScope.launch { - appDb.bookSourceDao.flowEnabledGroups().flowOn(IO).conflate().collect { + appDb.bookSourceDao.flowEnabledGroups().conflate().collect { groups.clear() groups.addAll(it) upGroupMenu() diff --git a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt index ce38a175f..58ef6678f 100644 --- a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt @@ -5,9 +5,11 @@ import android.net.Uri import android.os.Bundle import android.view.Menu import android.view.MenuItem +import androidx.activity.addCallback import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.documentfile.provider.DocumentFile +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R 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.utils.* import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Job import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.io.File /** @@ -49,7 +53,12 @@ class ImportBookActivity : BaseImportBookActivity(), override fun onActivityCreated(savedInstanceState: Bundle?) { searchView.queryHint = getString(R.string.screen) + " • " + getString(R.string.local_book) - launch { + onBackPressedDispatcher.addCallback(this) { + if (!goBackDir()) { + finish() + } + } + lifecycleScope.launch { initView() initEvent() if (setBookStorage() && AppConfig.importBookPath.isNullOrBlank()) { @@ -129,7 +138,7 @@ class ImportBookActivity : BaseImportBookActivity(), viewModel.dataFlowStart = { initRootDoc() } - launch { + lifecycleScope.launch { viewModel.dataFlow.conflate().collect { docs -> adapter.setItems(docs) } @@ -235,9 +244,9 @@ class ImportBookActivity : BaseImportBookActivity(), val lastDoc = viewModel.subDocs.lastOrNull() ?: doc binding.refreshProgressBar.isAutoLoading = true scanDocJob?.cancel() - scanDocJob = launch(IO) { - viewModel.scanDoc(lastDoc, true, this) { - launch { + scanDocJob = lifecycleScope.launch(IO) { + viewModel.scanDoc(lastDoc, true) { + withContext(Main) { binding.refreshProgressBar.isAutoLoading = false } } @@ -281,14 +290,6 @@ class ImportBookActivity : BaseImportBookActivity(), viewModel.updateCallBackFlow(newText) } - @Deprecated("Deprecated in Java") - override fun onBackPressed() { - if (!goBackDir()) { - @Suppress("DEPRECATION") - super.onBackPressed() - } - } - override fun upCountView() { binding.selectActionBar.upCountView(adapter.selectedUris.size, adapter.checkableCount) } diff --git a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookViewModel.kt index 5ca7603fa..ef3977f03 100644 --- a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookViewModel.kt @@ -9,8 +9,11 @@ import io.legado.app.constant.AppPattern.archiveFileRegex import io.legado.app.constant.AppPattern.bookFileRegex import io.legado.app.constant.PreferKey import io.legado.app.model.localBook.LocalBook -import io.legado.app.utils.* -import kotlinx.coroutines.CoroutineScope +import io.legado.app.utils.FileDoc +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.Main import kotlinx.coroutines.channels.awaitClose @@ -20,7 +23,8 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext import java.io.File -import java.util.* +import java.util.Collections +import kotlin.coroutines.coroutineContext class ImportBookViewModel(application: Application) : BaseViewModel(application) { var rootDoc: FileDoc? = null @@ -133,34 +137,35 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application) } } - fun scanDoc( + suspend fun scanDoc( fileDoc: FileDoc, isRoot: Boolean, - scope: CoroutineScope, - finally: (() -> Unit)? = null + finally: (suspend () -> Unit)? = null ) { if (isRoot) { dataCallback?.clear() } - if (!scope.isActive) { + if (!coroutineContext.isActive) { finally?.invoke() return } kotlin.runCatching { val list = ArrayList() fileDoc.list()!!.forEach { docItem -> - if (!scope.isActive) { + if (!coroutineContext.isActive) { finally?.invoke() return } if (docItem.isDir) { - scanDoc(docItem, false, scope) - } else if (docItem.name.matches(bookFileRegex) || docItem.name.matches(archiveFileRegex) + scanDoc(docItem, false) + } else if (docItem.name.matches(bookFileRegex) || docItem.name.matches( + archiveFileRegex + ) ) { list.add(docItem) } } - if (!scope.isActive) { + if (!coroutineContext.isActive) { finally?.invoke() return } diff --git a/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookActivity.kt index aeaf05c0f..8f384f2ca 100644 --- a/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookActivity.kt @@ -6,8 +6,10 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.SubMenu +import androidx.activity.addCallback import androidx.activity.viewModels import androidx.core.view.isGone +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.data.appDb @@ -43,7 +45,12 @@ class RemoteBookActivity : BaseImportBookActivity(), override fun onActivityCreated(savedInstanceState: Bundle?) { searchView.queryHint = getString(R.string.screen) + " • " + getString(R.string.remote_book) - launch { + onBackPressedDispatcher.addCallback(this) { + if (!goBackDir()) { + finish() + } + } + lifecycleScope.launch { if (!setBookStorage()) { finish() return@launch @@ -152,14 +159,6 @@ class RemoteBookActivity : BaseImportBookActivity(), } } - @Deprecated("Deprecated in Java") - override fun onBackPressed() { - if (!goBackDir()) { - @Suppress("DEPRECATION") - super.onBackPressed() - } - } - private fun goBackDir(): Boolean { if (viewModel.dirList.isEmpty()) { return false diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 254ff88c8..97bf4b9e4 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -10,6 +10,7 @@ import android.widget.CheckBox import android.widget.LinearLayout import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.Theme @@ -62,7 +63,7 @@ class BookInfoActivity : private val tocActivityResult = registerForActivityResult(TocActivityResult()) { it?.let { viewModel.getBook(false)?.let { book -> - launch { + lifecycleScope.launch { withContext(IO) { book.durChapterIndex = it.first book.durChapterPos = it.second @@ -247,7 +248,7 @@ class BookInfoActivity : book: Book, bookWebDav: RemoteBookWebDav? = AppWebDav.defaultBookWebDav ) { - launch { + lifecycleScope.launch { waitDialog.setText("上传中.....") waitDialog.show() try { @@ -431,13 +432,14 @@ class BookInfoActivity : } private fun setSourceVariable() { - launch { + lifecycleScope.launch { val source = viewModel.bookSource if (source == null) { toastOnUi("书源不存在") return@launch } - val comment = source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") + val comment = + source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") val variable = withContext(IO) { source.getVariable() } showDialogFragment( VariableDialog( @@ -451,7 +453,7 @@ class BookInfoActivity : } private fun setBookVariable() { - launch { + lifecycleScope.launch { val source = viewModel.bookSource if (source == null) { toastOnUi("书源不存在") diff --git a/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt b/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt index 331c34225..e0c72c02d 100644 --- a/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt @@ -11,6 +11,7 @@ import android.widget.LinearLayout import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R @@ -72,7 +73,7 @@ class BookshelfManageActivity : override fun onActivityCreated(savedInstanceState: Bundle?) { viewModel.groupId = intent.getLongExtra("groupId", -1) - launch { + lifecycleScope.launch { viewModel.groupName = withContext(IO) { appDb.bookGroupDao.getByID(viewModel.groupId)?.groupName ?: getString(R.string.no_group) @@ -184,7 +185,7 @@ class BookshelfManageActivity : @SuppressLint("NotifyDataSetChanged") private fun initGroupData() { - launch { + lifecycleScope.launch { appDb.bookGroupDao.flowAll().conflate().collect { groupList.clear() groupList.addAll(it) @@ -196,7 +197,7 @@ class BookshelfManageActivity : private fun upBookDataByGroupId() { booksFlowJob?.cancel() - booksFlowJob = launch { + booksFlowJob = lifecycleScope.launch { val bookSort = AppConfig.getBookSortByGroupId(viewModel.groupId) appDb.bookDao.flowByGroup(viewModel.groupId).map { list -> when (bookSort) { diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index bacc4e948..1b523aeea 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -13,6 +13,7 @@ import androidx.appcompat.widget.PopupMenu import androidx.core.view.get import androidx.core.view.isVisible import androidx.core.view.size +import androidx.lifecycle.lifecycleScope import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import io.legado.app.BuildConfig 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) { 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 chapter = appDb.bookChapterDao.getChapter(book.bookUrl, ReadBook.durChapterIndex) @@ -769,7 +770,7 @@ class ReadBookActivity : BaseReadBookActivity(), } override fun upMenuView() { - launch { + lifecycleScope.launch { upMenu() binding.readMenu.upBookView() } @@ -799,7 +800,7 @@ class ReadBookActivity : BaseReadBookActivity(), resetPageOffset: Boolean, success: (() -> Unit)? ) { - launch { + lifecycleScope.launch { autoPageProgress = 0 binding.readView.upContent(relativePosition, resetPageOffset) upSeekBarProgress() @@ -809,7 +810,7 @@ class ReadBookActivity : BaseReadBookActivity(), } override fun upPageAnim() { - launch { + lifecycleScope.launch { binding.readView.upPageAnim() } } @@ -822,7 +823,7 @@ class ReadBookActivity : BaseReadBookActivity(), * 页面改变 */ override fun pageChanged() { - launch { + lifecycleScope.launch { autoPageProgress = 0 upSeekBarProgress() startBackupJob() @@ -855,7 +856,7 @@ class ReadBookActivity : BaseReadBookActivity(), viewModel.changeTo(book, toc) } else { ReadAloud.stop(this) - launch { + lifecycleScope.launch { withContext(IO) { ReadBook.book?.migrateTo(book, toc) book.removeType(BookType.updateError) @@ -925,7 +926,7 @@ class ReadBookActivity : BaseReadBookActivity(), private fun autoPagePlus() { autoPageJob?.cancel() - autoPageJob = launch { + autoPageJob = lifecycleScope.launch { while (isActive) { var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height var scrollOffset = 1 @@ -1307,7 +1308,7 @@ class ReadBookActivity : BaseReadBookActivity(), private fun startBackupJob() { backupJob?.cancel() - backupJob = launch(IO) { + backupJob = lifecycleScope.launch(IO) { delay(300000) ReadBook.book?.let { AppWebDav.uploadBookProgress(it) @@ -1389,7 +1390,7 @@ class ReadBookActivity : BaseReadBookActivity(), } } observeEventSticky(EventBus.TTS_PROGRESS) { chapterStart -> - launch(IO) { + lifecycleScope.launch(IO) { if (BaseReadAloudService.isPlay()) { ReadBook.curTextChapter?.let { textChapter -> val pageIndex = ReadBook.durPageIndex @@ -1432,7 +1433,7 @@ class ReadBookActivity : BaseReadBookActivity(), */ override fun screenOffTimerStart() { keepScreenJon?.cancel() - keepScreenJon = launch { + keepScreenJon = lifecycleScope.launch { if (screenTimeOut < 0) { keepScreenOn(true) return@launch diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt index 6b1b23970..e3cf03860 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt @@ -11,6 +11,7 @@ import android.widget.TextView import androidx.activity.viewModels import androidx.appcompat.widget.SearchView import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView 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.databinding.ActivityBookSearchBinding 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.book.info.BookInfoActivity 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.visible import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Job import kotlinx.coroutines.flow.conflate -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import splitties.init.appCtx @@ -67,7 +80,7 @@ class SearchActivity : VMBaseActivity Unit = searchFinish@{ isEmpty -> if (!isEmpty || viewModel.searchScope.isAll()) return@searchFinish - launch { + lifecycleScope.launch { alert("搜索结果为空") { val precisionSearch = appCtx.getPrefBoolean(PreferKey.precisionSearch) if (precisionSearch) { @@ -280,7 +293,7 @@ class SearchActivity : VMBaseActivity appDb.searchKeywordDao.flowByTime() else -> appDb.searchKeywordDao.flowSearch(key) @@ -425,7 +438,7 @@ class SearchActivity : VMBaseActivity { searchView.setQuery(key, true) diff --git a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt index 48b2ac91e..982896d95 100644 --- a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt @@ -10,6 +10,7 @@ import android.widget.EditText import androidx.activity.viewModels import androidx.appcompat.widget.SearchView import androidx.core.view.allViews +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.AppLog @@ -172,7 +173,7 @@ class SearchContentActivity : } private fun initCacheFileNames(book: Book) { - initJob = async { + initJob = lifecycleScope.async { withContext(IO) { viewModel.cacheChapterNames.addAll(BookHelp.getChapterFiles(book)) } @@ -202,7 +203,7 @@ class SearchContentActivity : viewModel.lastQuery = query binding.refreshProgressBar.isAutoLoading = true binding.fbStop.visible() - searchJob = launch(IO) { + searchJob = lifecycleScope.launch(IO) { initJob?.await() kotlin.runCatching { appDb.bookChapterDao.getChapterList(viewModel.bookUrl).forEach { bookChapter -> diff --git a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugActivity.kt index 64b48f60b..f4eb7dd6c 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugActivity.kt @@ -7,6 +7,7 @@ import android.view.MenuItem import android.view.View import androidx.activity.viewModels import androidx.appcompat.widget.SearchView +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.databinding.ActivitySourceDebugBinding @@ -47,7 +48,7 @@ class BookSourceDebugActivity : VMBaseActivity - launch { + lifecycleScope.launch { adapter.addItem(msg) if (state == -1 || state == 1000) { binding.rotateLoading.gone() @@ -113,7 +114,7 @@ class BookSourceDebugActivity : VMBaseActivity - launch { + lifecycleScope.launch { val comment = source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") val variable = withContext(IO) { source.getVariable() } diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index e5af76801..ea6c08960 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -9,6 +9,7 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView import androidx.core.os.bundleOf +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import com.google.android.material.snackbar.Snackbar import io.legado.app.R @@ -249,7 +250,7 @@ class BookSourceActivity : VMBaseActivity { appDb.bookSourceDao.flowAll() @@ -337,8 +338,8 @@ class BookSourceActivity : VMBaseActivity adapter.setItems(tocRules, adapter.diffItemCallBack) upCountView() diff --git a/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleActivity.kt b/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleActivity.kt index 68dc094a6..50d5c2900 100644 --- a/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleActivity.kt @@ -6,6 +6,7 @@ import android.view.Menu import android.view.MenuItem import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R @@ -110,7 +111,7 @@ class DictRuleActivity : VMBaseActivity(), override fun onPostCreate(savedInstanceState: Bundle?) { super.onPostCreate(savedInstanceState) - launch { + lifecycleScope.launch { //隐私协议 if (!privacyPolicy()) return@launch //版本更新 @@ -269,7 +270,7 @@ class MainActivity : VMBaseActivity(), * 备份同步 */ private fun backupSync() { - launch { + lifecycleScope.launch { val lastBackupFile = withContext(IO) { AppWebDav.lastBackUp().getOrNull() } ?: return@launch if (lastBackupFile.lastModify - LocalConfig.lastBackup > DateUtils.MINUTE_IN_MILLIS) { diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt index 19d7592a1..a54deb085 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt @@ -130,7 +130,7 @@ class ExploreFragment() : VMBaseFragment(R.layout.fragment_exp private fun initGroupData() { lifecycleScope.launch { - appDb.bookSourceDao.flowExploreGroups().flowOn(IO).conflate().collect { + appDb.bookSourceDao.flowExploreGroups().conflate().collect { groups.clear() groups.addAll(it) upGroupsMenu() diff --git a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt index 370ef9e7d..f1d59ff7e 100644 --- a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt @@ -12,6 +12,7 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R @@ -189,14 +190,16 @@ class ReplaceRuleActivity : VMBaseActivity { appDb.replaceRuleDao.flowAll() } + searchKey == getString(R.string.no_group) -> { appDb.replaceRuleDao.flowNoGroup() } + searchKey.startsWith("group:") -> { val key = searchKey.substringAfter("group:") appDb.replaceRuleDao.flowGroupSearch("%$key%") @@ -218,7 +221,7 @@ class ReplaceRuleActivity : VMBaseActivity() private val softKeyboardTool by lazy { - KeyboardToolPop(this, this, binding.root, this) + KeyboardToolPop(this, lifecycleScope, binding.root, this) } override fun onActivityCreated(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt index cc8e3ea48..11d1dbf67 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt @@ -9,6 +9,7 @@ import android.view.ViewGroup import androidx.activity.viewModels import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.databinding.ActivityRssArtivlesBinding @@ -91,7 +92,7 @@ class RssSortActivity : VMBaseActivity(), } private fun initData() { - launch { + lifecycleScope.launch { appDb.rssStarDao.liveAll().conflate().collect { adapter.setItems(it) } diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt index a87700b74..92abc3240 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt @@ -11,6 +11,7 @@ import android.webkit.* import androidx.activity.addCallback import androidx.activity.viewModels import androidx.core.view.size +import androidx.lifecycle.lifecycleScope import com.script.rhino.RhinoScriptEngine import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -263,7 +264,7 @@ class ReadRssActivity : VMBaseActivity } private fun upTtsMenu(isPlaying: Boolean) { - launch { + lifecycleScope.launch { if (isPlaying) { ttsMenuItem?.setIcon(R.drawable.ic_stop_black_24dp) ttsMenuItem?.setTitle(R.string.aloud_stop) diff --git a/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt index 9b7578be7..1757c0739 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt @@ -5,6 +5,7 @@ import android.view.Menu import android.view.MenuItem import android.widget.SearchView import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.databinding.ActivitySourceDebugBinding @@ -30,7 +31,7 @@ class RssSourceDebugActivity : VMBaseActivity - launch { + lifecycleScope.launch { adapter.addItem(msg) if (state == -1 || state == 1000) { binding.rotateLoading.gone() diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt index a93816515..ec504ea02 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt @@ -6,6 +6,7 @@ import android.view.Menu import android.view.MenuItem import android.widget.EditText import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import com.google.android.material.tabs.TabLayout import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import io.legado.app.R @@ -50,7 +51,7 @@ class RssSourceEditActivity : override val binding by viewBinding(ActivityRssSourceEditBinding::inflate) override val viewModel by viewModels() 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 sourceEntities: ArrayList = ArrayList() @@ -328,7 +329,7 @@ class RssSourceEditActivity : private fun setSourceVariable() { viewModel.save(getRssSource()) { source -> - launch { + lifecycleScope.launch { val comment = source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取") val variable = withContext(Dispatchers.IO) { source.getVariable() } diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt index 63d49acec..1960bb8d5 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt @@ -10,6 +10,7 @@ import android.widget.EditText import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -219,7 +220,7 @@ class RssSourceActivity : VMBaseActivity { appDb.rssSourceDao.flowAll() } + searchKey == getString(R.string.enabled) -> { appDb.rssSourceDao.flowEnabled() } + searchKey == getString(R.string.disabled) -> { appDb.rssSourceDao.flowDisabled() } diff --git a/app/src/main/java/io/legado/app/ui/rss/subscription/RuleSubActivity.kt b/app/src/main/java/io/legado/app/ui/rss/subscription/RuleSubActivity.kt index 4aa9a374a..ee8c284a4 100644 --- a/app/src/main/java/io/legado/app/ui/rss/subscription/RuleSubActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/subscription/RuleSubActivity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.core.view.isGone +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import io.legado.app.R import io.legado.app.base.BaseActivity @@ -61,7 +62,7 @@ class RuleSubActivity : BaseActivity(), } private fun initData() { - launch { + lifecycleScope.launch { appDb.ruleSubDao.flowAll().conflate().collect { binding.tvEmptyMsg.isGone = it.isNotEmpty() adapter.setItems(it) @@ -92,7 +93,7 @@ class RuleSubActivity : BaseActivity(), } customView { alertBinding.root } okButton { - launch { + lifecycleScope.launch { ruleSub.type = alertBinding.spType.selectedItemPosition ruleSub.name = alertBinding.etName.text?.toString() ?: "" ruleSub.url = alertBinding.etUrl.text?.toString() ?: "" @@ -113,19 +114,19 @@ class RuleSubActivity : BaseActivity(), } override fun delSubscription(ruleSub: RuleSub) { - launch(IO) { + lifecycleScope.launch(IO) { appDb.ruleSubDao.delete(ruleSub) } } override fun updateSourceSub(vararg ruleSub: RuleSub) { - launch(IO) { + lifecycleScope.launch(IO) { appDb.ruleSubDao.update(*ruleSub) } } override fun upOrder() { - launch(IO) { + lifecycleScope.launch(IO) { val sourceSubs = appDb.ruleSubDao.all for ((index: Int, ruleSub: RuleSub) in sourceSubs.withIndex()) { ruleSub.customOrder = index + 1