Merge pull request #1936 from Xwite/master
fix(EpubFile/parseFirstPage): parse all contents
This commit is contained in:
@@ -153,8 +153,8 @@ class ContentProcessor private constructor(
|
|||||||
} catch (e: CancellationException) {
|
} catch (e: CancellationException) {
|
||||||
return mContent
|
return mContent
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
AppLog.put("${item.name}替换出错\n替换内容\n${mContent}", e)
|
AppLog.put("替换净化: 规则 ${item.name}替换出错\n替换内容\n${mContent}", e)
|
||||||
appCtx.toastOnUi("${item.name}替换出错")
|
appCtx.toastOnUi("替换净化: 规则 ${item.name}替换出错")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,14 @@ class EpubFile(var book: Book) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getContent(chapter: BookChapter): String? {
|
private fun getContent(chapter: BookChapter): String? {
|
||||||
|
/**
|
||||||
|
* <image width="1038" height="670" xlink:href="cover.jpeg"/>
|
||||||
|
* <img width="1038" height="670" src="cover.jpeg"/>
|
||||||
|
* titlepage.xhtml
|
||||||
|
*/
|
||||||
|
if (chapter.url == "titlepage.xhtml") {
|
||||||
|
return "<img src=\"cover.jpeg\" />"
|
||||||
|
}
|
||||||
/*获取当前章节文本*/
|
/*获取当前章节文本*/
|
||||||
epubBook?.let { epubBook ->
|
epubBook?.let { epubBook ->
|
||||||
val nextUrl = chapter.getVariable("nextUrl")
|
val nextUrl = chapter.getVariable("nextUrl")
|
||||||
@@ -139,10 +147,10 @@ class EpubFile(var book: Book) {
|
|||||||
* content src text/000001.html(当前章节)
|
* content src text/000001.html(当前章节)
|
||||||
- * content src text/000001.html#toc_id_x (下一章节)
|
- * 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) {
|
} else if (isChapter) {
|
||||||
// fix 最后一章存在多个html时 内容缺失
|
// fix 最后一章存在多个html时 内容缺失
|
||||||
if (!nextUrl.isNullOrBlank() && res.href == nextUrl.substringBeforeLast("#")) {
|
if (res.href == nextUrl?.substringBeforeLast("#")) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
elements.add(getBody(res, startFragmentId, endFragmentId))
|
elements.add(getBody(res, startFragmentId, endFragmentId))
|
||||||
@@ -188,6 +196,7 @@ class EpubFile(var book: Book) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getImage(href: String): InputStream? {
|
private fun getImage(href: String): InputStream? {
|
||||||
|
if (href == "cover.jpeg") return epubBook?.coverImage?.inputStream
|
||||||
val abHref = href.replace("../", "")
|
val abHref = href.replace("../", "")
|
||||||
return epubBook?.resources?.getByHref(abHref)?.inputStream
|
return epubBook?.resources?.getByHref(abHref)?.inputStream
|
||||||
}
|
}
|
||||||
@@ -276,8 +285,12 @@ class EpubFile(var book: Book) {
|
|||||||
while (i < contents.size) {
|
while (i < contents.size) {
|
||||||
val content = contents[i]
|
val content = contents[i]
|
||||||
if (!content.mediaType.toString().contains("htm")) continue
|
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()
|
val chapter = BookChapter()
|
||||||
var title = content.title
|
var title = content.title
|
||||||
if (TextUtils.isEmpty(title)) {
|
if (TextUtils.isEmpty(title)) {
|
||||||
|
|||||||
@@ -394,9 +394,10 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
|
|||||||
|
|
||||||
fun refreshImage(src: String) {
|
fun refreshImage(src: String) {
|
||||||
execute {
|
execute {
|
||||||
ImageProvider.bitmapLruCache.remove(src)
|
|
||||||
ReadBook.book?.let { book ->
|
ReadBook.book?.let { book ->
|
||||||
BookHelp.getImage(book, src).delete()
|
val vFile = BookHelp.getImage(book, src)
|
||||||
|
ImageProvider.bitmapLruCache.remove(vFile.absolutePath)
|
||||||
|
vFile.delete()
|
||||||
}
|
}
|
||||||
}.onFinally {
|
}.onFinally {
|
||||||
ReadBook.loadContent(false)
|
ReadBook.loadContent(false)
|
||||||
|
|||||||
@@ -28,26 +28,27 @@ object ImageProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*缓存bitmap LruCache实现
|
* 缓存bitmap LruCache实现
|
||||||
|
* filePath bitmap
|
||||||
*/
|
*/
|
||||||
private const val M = 1024 * 1024
|
private const val M = 1024 * 1024
|
||||||
val cacheSize get() = AppConfig.bitmapCacheSize * M
|
val cacheSize get() = AppConfig.bitmapCacheSize * M
|
||||||
val bitmapLruCache = object : LruCache<String, Bitmap>(cacheSize) {
|
val bitmapLruCache = object : LruCache<String, Bitmap>(cacheSize) {
|
||||||
|
|
||||||
override fun sizeOf(key: String, bitmap: Bitmap): Int {
|
override fun sizeOf(filePath: String, bitmap: Bitmap): Int {
|
||||||
return bitmap.byteCount
|
return bitmap.byteCount
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun entryRemoved(
|
override fun entryRemoved(
|
||||||
evicted: Boolean,
|
evicted: Boolean,
|
||||||
key: String,
|
filePath: String,
|
||||||
oldBitmap: Bitmap,
|
oldBitmap: Bitmap,
|
||||||
newBitmap: Bitmap?
|
newBitmap: Bitmap?
|
||||||
) {
|
) {
|
||||||
//错误图片不能释放,占位用,防止一直重复获取图片
|
//错误图片不能释放,占位用,防止一直重复获取图片
|
||||||
if (oldBitmap != errorBitmap) {
|
if (oldBitmap != errorBitmap) {
|
||||||
oldBitmap.recycle()
|
oldBitmap.recycle()
|
||||||
putDebug("ImageProvider: trigger bitmap recycle. URI: $key")
|
putDebug("ImageProvider: trigger bitmap recycle. URI: $filePath")
|
||||||
putDebug("ImageProvider : cacheUsage ${size()}bytes / ${maxSize()}bytes")
|
putDebug("ImageProvider : cacheUsage ${size()}bytes / ${maxSize()}bytes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,19 +113,21 @@ object ImageProvider {
|
|||||||
width: Int,
|
width: Int,
|
||||||
height: Int? = null
|
height: Int? = null
|
||||||
): Bitmap {
|
): Bitmap {
|
||||||
val cacheBitmap = bitmapLruCache.get(src)
|
|
||||||
if (cacheBitmap != null) return cacheBitmap
|
|
||||||
val vFile = BookHelp.getImage(book, src)
|
val vFile = BookHelp.getImage(book, src)
|
||||||
if (!vFile.exists()) return errorBitmap
|
if (!vFile.exists()) return errorBitmap
|
||||||
|
//epub文件提供图片链接是相对链接,同时阅读多个epub文件,缓存命中错误
|
||||||
|
//bitmapLruCache的key同一改成缓存文件的路径
|
||||||
|
val cacheBitmap = bitmapLruCache.get(vFile.absolutePath)
|
||||||
|
if (cacheBitmap != null) return cacheBitmap
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
||||||
?: throw NoStackTraceException("解析图片失败")
|
?: throw NoStackTraceException("解析图片失败")
|
||||||
bitmapLruCache.put(src, bitmap)
|
bitmapLruCache.put(vFile.absolutePath, bitmap)
|
||||||
bitmap
|
bitmap
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
//错误图片占位,防止重复获取
|
//错误图片占位,防止重复获取
|
||||||
bitmapLruCache.put(src, errorBitmap)
|
bitmapLruCache.put(vFile.absolutePath, errorBitmap)
|
||||||
putDebug(
|
putDebug(
|
||||||
"ImageProvider: decode bitmap failed. path: ${vFile.absolutePath}\n$it",
|
"ImageProvider: decode bitmap failed. path: ${vFile.absolutePath}\n$it",
|
||||||
it
|
it
|
||||||
|
|||||||
Reference in New Issue
Block a user