From b33b10bdc7eee44b7650ad956b1e9704e8bcf4e2 Mon Sep 17 00:00:00 2001 From: Horis <8674809+821938089@users.noreply.github.com> Date: Sat, 12 Apr 2025 14:53:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/help/glide/OkHttpStreamFetcher.kt | 3 +- .../app/model/analyzeRule/AnalyzeRule.kt | 2 +- .../io/legado/app/model/webBook/WebBook.kt | 15 +++------ .../app/ui/book/info/BookInfoActivity.kt | 9 +++--- .../book/manage/BookshelfManageViewModel.kt | 12 +++++-- .../app/ui/book/manga/ReadMangaViewModel.kt | 2 +- .../app/ui/book/read/ReadBookViewModel.kt | 2 +- .../app/ui/widget/image/CoverImageView.kt | 31 +++++++++++++++++-- 8 files changed, 53 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt b/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt index b984d8fc7..b41c09a2c 100644 --- a/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt +++ b/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt @@ -7,6 +7,7 @@ import com.bumptech.glide.load.Options import com.bumptech.glide.load.data.DataFetcher import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.util.ContentLengthInputStream +import com.script.rhino.runScriptWithContext import io.legado.app.data.entities.BaseSource import io.legado.app.exception.NoStackTraceException import io.legado.app.help.http.CookieManager.cookieJarHeader @@ -17,7 +18,6 @@ import io.legado.app.help.source.SourceHelp import io.legado.app.model.ReadManga import io.legado.app.utils.ImageUtils import io.legado.app.utils.isWifiConnect -import com.script.rhino.runScriptWithContext import kotlinx.coroutines.Job import okhttp3.Call import okhttp3.Request @@ -89,6 +89,7 @@ class OkHttpStreamFetcher( stream?.close() } responseBody?.close() + coroutineContext.cancel() callback = null } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 4eda23b07..39972ee5c 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -812,7 +812,7 @@ class AnalyzeRule( if (bookSource == null || book == null) return runBlocking(coroutineContext) { withTimeout(1800000) { - WebBook.preciseSearchAwait(this, bookSource, book.name, book.author) + WebBook.preciseSearchAwait(bookSource, book.name, book.author) .getOrThrow().let { book.bookUrl = it.bookUrl it.variableMap.forEach { entry -> diff --git a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt index 2698e6440..c9f4e232a 100644 --- a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt +++ b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt @@ -19,7 +19,7 @@ import io.legado.app.model.analyzeRule.RuleData import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.isActive +import kotlinx.coroutines.ensureActive import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withPermit import kotlin.coroutines.CoroutineContext @@ -363,7 +363,7 @@ object WebBook { return Coroutine.async(scope, context) { for (s in bookSourceParts) { val source = s.getBookSource() ?: continue - val book = preciseSearchAwait(scope, source, name, author).getOrNull() + val book = preciseSearchAwait(source, name, author).getOrNull() if (book != null) { return@async Pair(book, source) } @@ -373,24 +373,19 @@ object WebBook { } suspend fun preciseSearchAwait( - scope: CoroutineScope, bookSource: BookSource, name: String, author: String, ): Result { return kotlin.runCatching { - scope.isActive + coroutineContext.ensureActive() searchBookAwait( bookSource, name, filter = { fName, fAuthor -> fName == name && fAuthor == author }, shouldBreak = { it > 0 } ).firstOrNull()?.let { searchBook -> - scope.isActive - var book = searchBook.toBook() - if (book.tocUrl.isBlank()) { - book = getBookInfoAwait(bookSource, book) - } - return@runCatching book + coroutineContext.ensureActive() + return@runCatching searchBook.toBook() } throw NoStackTraceException("未搜索到 $name($author) 书籍") } 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 10a8354dd..0b59d9f1a 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 @@ -350,10 +350,11 @@ class BookInfoActivity : } private fun showCover(book: Book) { - binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin) - if (!AppConfig.isEInkMode) { - BookCover.loadBlur(this, book.getDisplayCover()) - .into(binding.bgBook) + binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin) { + if (!AppConfig.isEInkMode) { + BookCover.loadBlur(this, book.getDisplayCover(), false, book.origin) + .into(binding.bgBook) + } } } diff --git a/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt b/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt index 0bb1754bf..8a8c79cb9 100644 --- a/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt @@ -87,10 +87,18 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica batchChangeSourceProcessLiveData.postValue("${index + 1} / ${books.size}") if (book.isLocal) return@forEachIndexed if (book.origin == source.bookSourceUrl) return@forEachIndexed - val newBook = WebBook.preciseSearchAwait(this, source, book.name, book.author) + val newBook = WebBook.preciseSearchAwait(source, book.name, book.author) .onFailure { - AppLog.put("获取书籍出错\n${it.localizedMessage}", it, true) + AppLog.put("搜索书籍出错\n${it.localizedMessage}", it, true) }.getOrNull() ?: return@forEachIndexed + kotlin.runCatching { + if (book.tocUrl.isEmpty()) { + WebBook.getBookInfoAwait(source, book) + } + }.onFailure { + AppLog.put("获取书籍详情出错\n${it.localizedMessage}", it, true) + return@forEachIndexed + } WebBook.getChapterListAwait(source, newBook) .onFailure { AppLog.put("获取目录出错\n${it.localizedMessage}", it, true) diff --git a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt index b74c8229f..ee41edd09 100644 --- a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt @@ -152,7 +152,7 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application) // 自动换源 }.mapParallelSafe(AppConfig.threadCount) { source -> - val book = WebBook.preciseSearchAwait(this, source, name, author).getOrThrow() + val book = WebBook.preciseSearchAwait(source, name, author).getOrThrow() if (book.tocUrl.isEmpty()) { WebBook.getBookInfoAwait(source, book) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index de7582825..94adee455 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -292,7 +292,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { }.onStart { ReadBook.upMsg(context.getString(R.string.source_auto_changing)) }.mapParallelSafe(AppConfig.threadCount) { source -> - val book = WebBook.preciseSearchAwait(this, source, name, author).getOrThrow() + val book = WebBook.preciseSearchAwait(source, name, author).getOrThrow() if (book.tocUrl.isEmpty()) { WebBook.getBookInfoAwait(source, book) } diff --git a/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt b/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt index e7ea63ed8..8c11d3ec2 100644 --- a/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt @@ -195,7 +195,8 @@ class CoverImageView @JvmOverloads constructor( loadOnlyWifi: Boolean = false, sourceOrigin: String? = null, fragment: Fragment? = null, - lifecycle: Lifecycle? = null + lifecycle: Lifecycle? = null, + onLoadFinish: (() -> Unit)? = null ) { this.bitmapPath = path this.name = name?.replace(AppPattern.bdRegex, "")?.trim() @@ -210,15 +211,39 @@ class CoverImageView @JvmOverloads constructor( if (sourceOrigin != null) { options = options.set(OkHttpModelLoader.sourceOriginOption, sourceOrigin) } - val builder = if (fragment != null && lifecycle != null) { + var builder = if (fragment != null && lifecycle != null) { ImageLoader.load(fragment, lifecycle, path) } else { ImageLoader.load(context, path)//Glide自动识别http://,content://和file:// } - builder.apply(options) + builder = builder.apply(options) .placeholder(BookCover.defaultDrawable) .error(BookCover.defaultDrawable) .listener(glideListener) + if (onLoadFinish != null) { + builder = builder.addListener(object : RequestListener { + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target, + isFirstResource: Boolean + ): Boolean { + return false + } + + override fun onResourceReady( + resource: Drawable, + model: Any, + target: Target?, + dataSource: DataSource, + isFirstResource: Boolean + ): Boolean { + onLoadFinish.invoke() + return false + } + }) + } + builder .centerCrop() .into(this) }