From dc24fc18f3977011b936a975fff037d5d5064b10 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 1 Sep 2020 08:26:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E7=89=87=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/help/BookHelp.kt | 15 +++++++++++++-- .../app/ui/book/read/ReadBookActivity.kt | 2 ++ .../app/ui/book/read/page/ContentTextView.kt | 18 +++++++++--------- .../book/read/page/provider/ChapterProvider.kt | 8 ++++---- .../book/read/page/provider/ImageProvider.kt | 17 +++++++++-------- .../legado/app/ui/widget/dialog/PhotoDialog.kt | 12 ++++++++---- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt index 355b7454e..94707b985 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -13,16 +13,19 @@ import io.legado.app.model.localBook.LocalBook import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.delay import kotlinx.coroutines.withContext import org.apache.commons.text.similarity.JaccardSimilarity import org.jetbrains.anko.toast import java.io.File +import java.util.concurrent.CopyOnWriteArraySet import kotlin.math.min object BookHelp { private const val cacheFolderName = "book_cache" private const val cacheImageFolderName = "images" private val downloadDir: File = App.INSTANCE.externalFilesDir + private val downloadImages = CopyOnWriteArraySet() fun formatChapterName(bookChapter: BookChapter): String { return String.format( @@ -61,7 +64,7 @@ object BookHelp { } } - fun saveContent(book: Book, bookChapter: BookChapter, content: String) { + suspend fun saveContent(book: Book, bookChapter: BookChapter, content: String) { if (content.isEmpty()) return //保存文本 FileUtils.createFileIfNotExist( @@ -84,7 +87,14 @@ object BookHelp { postEvent(EventBus.SAVE_CONTENT, bookChapter) } - fun saveImage(book: Book, src: String) { + suspend fun saveImage(book: Book, src: String) { + while (downloadImages.contains(src)) { + delay(100) + } + if (getImage(book, src).exists()) { + return + } + downloadImages.add(src) val analyzeUrl = AnalyzeUrl(src) analyzeUrl.getImageBytes(book.origin)?.let { FileUtils.createFileIfNotExist( @@ -95,6 +105,7 @@ object BookHelp { "${MD5Utils.md5Encode16(src)}${getImageSuffix(src)}" ).writeBytes(it) } + downloadImages.remove(src) } fun getImage(book: Book, src: String): File { diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 3e1c82259..ec8bd7285 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -55,6 +55,7 @@ import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_book_read.* import kotlinx.android.synthetic.main.view_read_menu.* +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch import org.jetbrains.anko.sdk27.listeners.onClick @@ -84,6 +85,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo override val viewModel: ReadBookViewModel get() = getViewModel(ReadBookViewModel::class.java) + override val scope: CoroutineScope get() = this override val isInitFinish: Boolean get() = viewModel.isInitFinish private val mHandler = Handler() diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index d21988163..c1de92f21 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -20,6 +20,7 @@ import io.legado.app.ui.widget.dialog.PhotoDialog import io.legado.app.utils.activity import io.legado.app.utils.getCompatColor import io.legado.app.utils.getPrefBoolean +import kotlinx.coroutines.CoroutineScope class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, attrs) { @@ -105,7 +106,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at private fun draw( canvas: Canvas, textLine: TextLine, - relativeOffset: Float + relativeOffset: Float, ) { val lineTop = textLine.lineTop + relativeOffset val lineBase = textLine.lineBase + relativeOffset @@ -135,7 +136,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at lineBase: Float, lineBottom: Float, isTitle: Boolean, - isReadAloud: Boolean + isReadAloud: Boolean, ) { val textPaint = if (isTitle) ChapterProvider.titlePaint else ChapterProvider.contentPaint textPaint.color = @@ -155,16 +156,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at canvas: Canvas, textLine: TextLine, lineTop: Float, - lineBottom: Float + lineBottom: Float, ) { textLine.textChars.forEach { textChar -> val rectF = RectF(textChar.start, lineTop, textChar.end, lineBottom) - ImageProvider.getImage( - ReadBook.book!!, + ImageProvider.getImage(ReadBook.book!!, textPage.chapterIndex, textChar.charData, - true - )?.let { + true)?.let { canvas.drawBitmap(it, null, rectF, null) } } @@ -211,7 +210,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at fun selectText( x: Float, y: Float, - select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit + select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit, ) { if (!selectAble) return if (!visibleRect.contains(x, y)) return @@ -257,7 +256,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at lineIndex: Int, charIndex: Int, relativeOffset: Float, - select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit + select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit, ) { if (textChar.isImage) { activity?.supportFragmentManager?.let { @@ -613,5 +612,6 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at fun onCancelSelect() val headerHeight: Int val pageFactory: TextPageFactory + val scope: CoroutineScope } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index f22b91933..cac399fcf 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -45,12 +45,12 @@ object ChapterProvider { /** * 获取拆分完的章节数据 */ - fun getTextChapter( + suspend fun getTextChapter( book: Book, bookChapter: BookChapter, contents: List, chapterSize: Int, - imageStyle: String? + imageStyle: String?, ): TextChapter { val textPages = arrayListOf() val pageLines = arrayListOf() @@ -110,13 +110,13 @@ object ChapterProvider { ) } - private fun setTypeImage( + private suspend fun setTypeImage( book: Book, chapter: BookChapter, src: String, y: Float, textPages: ArrayList, - imageStyle: String? + imageStyle: String?, ): Float { var durY = y ImageProvider.getImage(book, chapter.index, src)?.let { 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 30ac0a613..c269a7e55 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 @@ -1,13 +1,12 @@ package io.legado.app.ui.book.read.page.provider import android.graphics.Bitmap -import io.legado.app.App import io.legado.app.data.entities.Book import io.legado.app.help.BookHelp import io.legado.app.model.localBook.EPUBFile import io.legado.app.utils.BitmapUtils import io.legado.app.utils.FileUtils -import io.legado.app.utils.externalFilesDir +import kotlinx.coroutines.runBlocking import java.io.FileOutputStream import java.util.concurrent.ConcurrentHashMap @@ -37,14 +36,16 @@ object ImageProvider { val vFile = BookHelp.getImage(book, src) if (!vFile.exists()) { if (book.isEpub()) { - EPUBFile.getImage(book, src).use { - val out = FileOutputStream(FileUtils.createFileIfNotExist(vFile.absolutePath)) - it?.copyTo(out) - out.flush() - out.close() + EPUBFile.getImage(book, src)?.use { input -> + val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath) + FileOutputStream(newFile).use { output -> + input.copyTo(output) + } } } else if (!onUi) { - BookHelp.saveImage(book, src) + runBlocking { + BookHelp.saveImage(book, src) + } } } return try { diff --git a/app/src/main/java/io/legado/app/ui/widget/dialog/PhotoDialog.kt b/app/src/main/java/io/legado/app/ui/widget/dialog/PhotoDialog.kt index 74dfe23cd..36397a201 100644 --- a/app/src/main/java/io/legado/app/ui/widget/dialog/PhotoDialog.kt +++ b/app/src/main/java/io/legado/app/ui/widget/dialog/PhotoDialog.kt @@ -20,7 +20,7 @@ class PhotoDialog : BaseDialogFragment() { fun show( fragmentManager: FragmentManager, chapterIndex: Int, - src: String + src: String, ) { PhotoDialog().apply { val bundle = Bundle() @@ -45,7 +45,7 @@ class PhotoDialog : BaseDialogFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + savedInstanceState: Bundle?, ): View? { return inflater.inflate(R.layout.dialog_photo_view, container) } @@ -56,8 +56,12 @@ class PhotoDialog : BaseDialogFragment() { val src = it.getString("src") ReadBook.book?.let { book -> src?.let { - ImageProvider.getImage(book, chapterIndex, src)?.let { bitmap -> - photo_view.setImageBitmap(bitmap) + execute { + ImageProvider.getImage(book, chapterIndex, src) + }.onSuccess { bitmap -> + if (bitmap != null) { + photo_view.setImageBitmap(bitmap) + } } } }