diff --git a/app/src/main/java/io/legado/app/help/ContentProcessor.kt b/app/src/main/java/io/legado/app/help/ContentProcessor.kt index d479a58f8..0fc46dd1a 100644 --- a/app/src/main/java/io/legado/app/help/ContentProcessor.kt +++ b/app/src/main/java/io/legado/app/help/ContentProcessor.kt @@ -153,8 +153,8 @@ class ContentProcessor private constructor( } catch (e: CancellationException) { return mContent } catch (e: Exception) { - AppLog.put("${item.name}替换出错\n替换内容\n${mContent}", e) - appCtx.toastOnUi("${item.name}替换出错") + AppLog.put("替换净化: 规则 ${item.name}替换出错\n替换内容\n${mContent}", e) + appCtx.toastOnUi("替换净化: 规则 ${item.name}替换出错") } } } diff --git a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt index f8123abac..5d4d36e96 100644 --- a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt @@ -121,6 +121,14 @@ class EpubFile(var book: Book) { } private fun getContent(chapter: BookChapter): String? { + /** + * + * + * titlepage.xhtml + */ + if (chapter.url == "titlepage.xhtml") { + return "" + } /*获取当前章节文本*/ epubBook?.let { epubBook -> val nextUrl = chapter.getVariable("nextUrl") @@ -139,10 +147,10 @@ class EpubFile(var book: Book) { * content src text/000001.html(当前章节) - * content src text/000001.html#toc_id_x (下一章节) */ - if (!nextUrl.isNullOrBlank() && res.href == nextUrl!!.substringBeforeLast("#")) break + if (res.href == nextUrl?.substringBeforeLast("#")) break } else if (isChapter) { // fix 最后一章存在多个html时 内容缺失 - if (!nextUrl.isNullOrBlank() && res.href == nextUrl.substringBeforeLast("#")) { + if (res.href == nextUrl?.substringBeforeLast("#")) { break } elements.add(getBody(res, startFragmentId, endFragmentId)) @@ -188,6 +196,7 @@ class EpubFile(var book: Book) { } private fun getImage(href: String): InputStream? { + if (href == "cover.jpeg") return epubBook?.coverImage?.inputStream val abHref = href.replace("../", "") return epubBook?.resources?.getByHref(abHref)?.inputStream } @@ -276,8 +285,12 @@ class EpubFile(var book: Book) { while (i < contents.size) { val content = contents[i] if (!content.mediaType.toString().contains("htm")) continue - /*检索到第一章href停止*/ - if (refs[0].completeHref == content.href) break + /** + * 检索到第一章href停止 + * completeHref可能有fragment(#id) 必须去除 + * fix https://github.com/gedoor/legado/issues/1932 + */ + if (refs[0].completeHref.substringBeforeLast("#") == content.href) break val chapter = BookChapter() var title = content.title if (TextUtils.isEmpty(title)) { 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 4f2094184..339df6767 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 @@ -394,9 +394,10 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { fun refreshImage(src: String) { execute { - ImageProvider.bitmapLruCache.remove(src) ReadBook.book?.let { book -> - BookHelp.getImage(book, src).delete() + val vFile = BookHelp.getImage(book, src) + ImageProvider.bitmapLruCache.remove(vFile.absolutePath) + vFile.delete() } }.onFinally { ReadBook.loadContent(false) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index f485ab7be..549372c51 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -28,26 +28,27 @@ object ImageProvider { } /** - *缓存bitmap LruCache实现 + * 缓存bitmap LruCache实现 + * filePath bitmap */ private const val M = 1024 * 1024 val cacheSize get() = AppConfig.bitmapCacheSize * M val bitmapLruCache = object : LruCache(cacheSize) { - override fun sizeOf(key: String, bitmap: Bitmap): Int { + override fun sizeOf(filePath: String, bitmap: Bitmap): Int { return bitmap.byteCount } override fun entryRemoved( evicted: Boolean, - key: String, + filePath: String, oldBitmap: Bitmap, newBitmap: Bitmap? ) { //错误图片不能释放,占位用,防止一直重复获取图片 if (oldBitmap != errorBitmap) { oldBitmap.recycle() - putDebug("ImageProvider: trigger bitmap recycle. URI: $key") + putDebug("ImageProvider: trigger bitmap recycle. URI: $filePath") putDebug("ImageProvider : cacheUsage ${size()}bytes / ${maxSize()}bytes") } } @@ -112,19 +113,21 @@ object ImageProvider { width: Int, height: Int? = null ): Bitmap { - val cacheBitmap = bitmapLruCache.get(src) - if (cacheBitmap != null) return cacheBitmap val vFile = BookHelp.getImage(book, src) if (!vFile.exists()) return errorBitmap + //epub文件提供图片链接是相对链接,同时阅读多个epub文件,缓存命中错误 + //bitmapLruCache的key同一改成缓存文件的路径 + val cacheBitmap = bitmapLruCache.get(vFile.absolutePath) + if (cacheBitmap != null) return cacheBitmap @Suppress("BlockingMethodInNonBlockingContext") return kotlin.runCatching { val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height) ?: throw NoStackTraceException("解析图片失败") - bitmapLruCache.put(src, bitmap) + bitmapLruCache.put(vFile.absolutePath, bitmap) bitmap }.onFailure { //错误图片占位,防止重复获取 - bitmapLruCache.put(src, errorBitmap) + bitmapLruCache.put(vFile.absolutePath, errorBitmap) putDebug( "ImageProvider: decode bitmap failed. path: ${vFile.absolutePath}\n$it", it