General fixes (#19)
* fix OOM crash by refactoring EpubImage to use lazy loading - Removed raw image ByteArray from EpubImage data class to prevent OutOfMemoryErrors on large books. - Updated EpubParser and MobiParser to only store image paths in the EpubBook object. - Images are now loaded on-demand from disk via file URIs in WebView and Coil, reducing initial heap allocation. * fix(tts): resolve OutOfMemoryError by removing large strings from state bundle - Removed 'currentText' from the TtsState bundle inside MediaSession custom layout. - Updated TtsController to retrieve the current text chunk via MediaItem metadata. - This prevents heap exhaustion caused by high-frequency serialization of large text strings during word tracking and polling updates.
This commit is contained in:
parent
a81df6921d
commit
d6837aa4df
5 changed files with 23 additions and 47 deletions
|
|
@ -577,30 +577,29 @@ class EpubParser(private val context: Context) {
|
|||
private fun parseEpubImages(
|
||||
manifestItems: Map<String, EpubManifestItem>,
|
||||
filesContentMap: Map<String, EpubFile>,
|
||||
extractionRoot: File // Add this param
|
||||
@Suppress("UNUSED_PARAMETER") extractionRoot: File
|
||||
): List<EpubImage> {
|
||||
val imageExtensions = listOf("png", "gif", "jpg", "jpeg", "webp", "svg").map { ".$it" }
|
||||
val imageExtensions = setOf(".png", ".gif", ".jpg", ".jpeg", ".webp", ".svg")
|
||||
|
||||
val listedImages = manifestItems.values
|
||||
.filter { it.mediaType.startsWith("image/") }
|
||||
.mapNotNull { manifestItem ->
|
||||
val bytes = filesContentMap[manifestItem.absPath]?.data?.takeIf { it.isNotEmpty() }
|
||||
?: File(extractionRoot, manifestItem.absPath).takeIf { it.exists() }?.readBytes()
|
||||
|
||||
bytes?.let { EpubImage(absPath = manifestItem.absPath, image = it) }
|
||||
.map { manifestItem ->
|
||||
EpubImage(absPath = manifestItem.absPath)
|
||||
}
|
||||
|
||||
val unlistedImages = filesContentMap.asSequence()
|
||||
.filter { (path, _) -> imageExtensions.any { path.endsWith(it, ignoreCase = true) } }
|
||||
.filterNot { (path, _) -> listedImages.any { it.absPath == path } }
|
||||
.mapNotNull { (path, file) ->
|
||||
val bytes = file.data.takeIf { it.isNotEmpty() }
|
||||
?: File(extractionRoot, path).takeIf { it.exists() }?.readBytes()
|
||||
val listedPaths = listedImages.map { it.absPath }.toSet()
|
||||
|
||||
bytes?.let { EpubImage(absPath = path, image = it) }
|
||||
val unlistedImages = filesContentMap.keys
|
||||
.filter { path ->
|
||||
val lowerPath = path.lowercase()
|
||||
imageExtensions.any { lowerPath.endsWith(it) } && !listedPaths.contains(path)
|
||||
}
|
||||
.map { path ->
|
||||
EpubImage(absPath = path)
|
||||
}
|
||||
|
||||
return (listedImages + unlistedImages).distinctBy { it.absPath }.toList()
|
||||
Timber.d("Identified ${listedImages.size + unlistedImages.size} images (content not loaded into memory).")
|
||||
return (listedImages + unlistedImages).distinctBy { it.absPath }
|
||||
}
|
||||
|
||||
private fun parseCoverImage(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue