Horis 1 год назад
Родитель
Сommit
2cd8013aa8

+ 2 - 1
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
     }
 

+ 1 - 1
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 ->

+ 5 - 10
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<Book> {
         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) 书籍")
         }

+ 5 - 4
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)
+            }
         }
     }
 

+ 10 - 2
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)

+ 1 - 1
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)
                 }

+ 1 - 1
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)
                 }

+ 28 - 3
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<Drawable> {
+                    override fun onLoadFailed(
+                        e: GlideException?,
+                        model: Any?,
+                        target: Target<Drawable?>,
+                        isFirstResource: Boolean
+                    ): Boolean {
+                        return false
+                    }
+
+                    override fun onResourceReady(
+                        resource: Drawable,
+                        model: Any,
+                        target: Target<Drawable?>?,
+                        dataSource: DataSource,
+                        isFirstResource: Boolean
+                    ): Boolean {
+                        onLoadFinish.invoke()
+                        return false
+                    }
+                })
+            }
+            builder
                 .centerCrop()
                 .into(this)
         }