mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Make loader implementation classes internal
This commit is contained in:
		@@ -28,7 +28,6 @@ import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Chapter
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.toDomainChapter
 | 
			
		||||
import eu.kanade.tachiyomi.data.download.DownloadManager
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.loader.DownloadPageLoader
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
 | 
			
		||||
import tachiyomi.domain.chapter.service.calculateChapterGap
 | 
			
		||||
import tachiyomi.domain.manga.model.Manga
 | 
			
		||||
@@ -43,7 +42,7 @@ fun ChapterTransition(
 | 
			
		||||
    manga ?: return
 | 
			
		||||
 | 
			
		||||
    val currChapter = transition.from.chapter
 | 
			
		||||
    val currChapterDownloaded = transition.from.pageLoader is DownloadPageLoader
 | 
			
		||||
    val currChapterDownloaded = transition.from.pageLoader?.isLocal == true
 | 
			
		||||
 | 
			
		||||
    val goingToChapter = transition.to?.chapter
 | 
			
		||||
    val goingToChapterDownloaded = if (goingToChapter != null) {
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.HttpSource
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.loader.ChapterLoader
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.loader.DownloadPageLoader
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.loader.HttpPageLoader
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
 | 
			
		||||
@@ -365,7 +363,7 @@ class ReaderViewModel(
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (chapter.pageLoader is HttpPageLoader) {
 | 
			
		||||
        if (chapter.pageLoader?.isLocal == false) {
 | 
			
		||||
            val manga = manga ?: return
 | 
			
		||||
            val dbChapter = chapter.chapter
 | 
			
		||||
            val isDownloaded = downloadManager.isChapterDownloaded(
 | 
			
		||||
@@ -440,7 +438,7 @@ class ReaderViewModel(
 | 
			
		||||
        if (amount == 0 || !manga.favorite) return
 | 
			
		||||
 | 
			
		||||
        // Only download ahead if current + next chapter is already downloaded too to avoid jank
 | 
			
		||||
        if (getCurrentChapter()?.pageLoader !is DownloadPageLoader) return
 | 
			
		||||
        if (getCurrentChapter()?.pageLoader?.isLocal == true) return
 | 
			
		||||
        val nextChapter = state.value.viewerChapters?.nextChapter?.chapter ?: return
 | 
			
		||||
 | 
			
		||||
        viewModelScope.launchIO {
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,10 @@ import java.io.FileInputStream
 | 
			
		||||
/**
 | 
			
		||||
 * Loader used to load a chapter from a directory given on [file].
 | 
			
		||||
 */
 | 
			
		||||
class DirectoryPageLoader(val file: File) : PageLoader() {
 | 
			
		||||
internal class DirectoryPageLoader(val file: File) : PageLoader() {
 | 
			
		||||
 | 
			
		||||
    override var isLocal: Boolean = true
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the pages found on this directory ordered with a natural comparator.
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun getPages(): List<ReaderPage> {
 | 
			
		||||
        return file.listFiles()
 | 
			
		||||
            ?.filter { !it.isDirectory && ImageUtil.isImage(it.name) { FileInputStream(it) } }
 | 
			
		||||
@@ -28,9 +27,4 @@ class DirectoryPageLoader(val file: File) : PageLoader() {
 | 
			
		||||
            }
 | 
			
		||||
            .orEmpty()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * No additional action required to load the page
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun loadPage(page: ReaderPage) {}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ import java.io.File
 | 
			
		||||
/**
 | 
			
		||||
 * Loader used to load a chapter from the downloaded chapters.
 | 
			
		||||
 */
 | 
			
		||||
class DownloadPageLoader(
 | 
			
		||||
internal class DownloadPageLoader(
 | 
			
		||||
    private val chapter: ReaderChapter,
 | 
			
		||||
    private val manga: Manga,
 | 
			
		||||
    private val source: Source,
 | 
			
		||||
@@ -25,19 +25,12 @@ class DownloadPageLoader(
 | 
			
		||||
    private val downloadProvider: DownloadProvider,
 | 
			
		||||
) : PageLoader() {
 | 
			
		||||
 | 
			
		||||
    // Needed to open input streams
 | 
			
		||||
    private val context: Application by injectLazy()
 | 
			
		||||
 | 
			
		||||
    private var zipPageLoader: ZipPageLoader? = null
 | 
			
		||||
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        zipPageLoader?.recycle()
 | 
			
		||||
    }
 | 
			
		||||
    override var isLocal: Boolean = true
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the pages found on this downloaded chapter.
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun getPages(): List<ReaderPage> {
 | 
			
		||||
        val dbChapter = chapter.chapter
 | 
			
		||||
        val chapterPath = downloadProvider.findChapterDir(dbChapter.name, dbChapter.scanlator, manga.title, source)
 | 
			
		||||
@@ -48,6 +41,11 @@ class DownloadPageLoader(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        zipPageLoader?.recycle()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun getPagesFromArchive(chapterPath: UniFile): List<ReaderPage> {
 | 
			
		||||
        val loader = ZipPageLoader(File(chapterPath.filePath!!)).also { zipPageLoader = it }
 | 
			
		||||
        return loader.getPages()
 | 
			
		||||
 
 | 
			
		||||
@@ -8,24 +8,12 @@ import java.io.File
 | 
			
		||||
/**
 | 
			
		||||
 * Loader used to load a chapter from a .epub file.
 | 
			
		||||
 */
 | 
			
		||||
class EpubPageLoader(file: File) : PageLoader() {
 | 
			
		||||
internal class EpubPageLoader(file: File) : PageLoader() {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The epub file.
 | 
			
		||||
     */
 | 
			
		||||
    private val epub = EpubFile(file)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recycles this loader and the open zip.
 | 
			
		||||
     */
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        epub.close()
 | 
			
		||||
    }
 | 
			
		||||
    override var isLocal: Boolean = true
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the pages found on this zip archive ordered with a natural comparator.
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun getPages(): List<ReaderPage> {
 | 
			
		||||
        return epub.getImagesFromPages()
 | 
			
		||||
            .mapIndexed { i, path ->
 | 
			
		||||
@@ -37,10 +25,12 @@ class EpubPageLoader(file: File) : PageLoader() {
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * No additional action required to load the page
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun loadPage(page: ReaderPage) {
 | 
			
		||||
        check(!isRecycled)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        epub.close()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ import kotlin.math.min
 | 
			
		||||
/**
 | 
			
		||||
 * Loader used to load chapters from an online source.
 | 
			
		||||
 */
 | 
			
		||||
class HttpPageLoader(
 | 
			
		||||
internal class HttpPageLoader(
 | 
			
		||||
    private val chapter: ReaderChapter,
 | 
			
		||||
    private val source: HttpSource,
 | 
			
		||||
    private val chapterCache: ChapterCache = Injekt.get(),
 | 
			
		||||
@@ -56,30 +56,7 @@ class HttpPageLoader(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recycles this loader and the active subscriptions and queue.
 | 
			
		||||
     */
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        scope.cancel()
 | 
			
		||||
        queue.clear()
 | 
			
		||||
 | 
			
		||||
        // Cache current page list progress for online chapters to allow a faster reopen
 | 
			
		||||
        val pages = chapter.pages
 | 
			
		||||
        if (pages != null) {
 | 
			
		||||
            launchIO {
 | 
			
		||||
                try {
 | 
			
		||||
                    // Convert to pages without reader information
 | 
			
		||||
                    val pagesToSave = pages.map { Page(it.index, it.url, it.imageUrl) }
 | 
			
		||||
                    chapterCache.putPageListToCache(chapter.chapter.toDomainChapter()!!, pagesToSave)
 | 
			
		||||
                } catch (e: Throwable) {
 | 
			
		||||
                    if (e is CancellationException) {
 | 
			
		||||
                        throw e
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    override var isLocal: Boolean = false
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the page list for a chapter. It tries to return the page list from the local cache,
 | 
			
		||||
@@ -135,8 +112,41 @@ class HttpPageLoader(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retries a page. This method is only called from user interaction on the viewer.
 | 
			
		||||
     */
 | 
			
		||||
    override fun retryPage(page: ReaderPage) {
 | 
			
		||||
        if (page.status == Page.State.ERROR) {
 | 
			
		||||
            page.status = Page.State.QUEUE
 | 
			
		||||
        }
 | 
			
		||||
        queue.offer(PriorityPage(page, 2))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        scope.cancel()
 | 
			
		||||
        queue.clear()
 | 
			
		||||
 | 
			
		||||
        // Cache current page list progress for online chapters to allow a faster reopen
 | 
			
		||||
        val pages = chapter.pages
 | 
			
		||||
        if (pages != null) {
 | 
			
		||||
            launchIO {
 | 
			
		||||
                try {
 | 
			
		||||
                    // Convert to pages without reader information
 | 
			
		||||
                    val pagesToSave = pages.map { Page(it.index, it.url, it.imageUrl) }
 | 
			
		||||
                    chapterCache.putPageListToCache(chapter.chapter.toDomainChapter()!!, pagesToSave)
 | 
			
		||||
                } catch (e: Throwable) {
 | 
			
		||||
                    if (e is CancellationException) {
 | 
			
		||||
                        throw e
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Preloads the given [amount] of pages after the [currentPage] with a lower priority.
 | 
			
		||||
     *
 | 
			
		||||
     * @return a list of [PriorityPage] that were added to the [queue]
 | 
			
		||||
     */
 | 
			
		||||
    private fun preloadNextPages(currentPage: ReaderPage, amount: Int): List<PriorityPage> {
 | 
			
		||||
@@ -155,35 +165,6 @@ class HttpPageLoader(
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retries a page. This method is only called from user interaction on the viewer.
 | 
			
		||||
     */
 | 
			
		||||
    override fun retryPage(page: ReaderPage) {
 | 
			
		||||
        if (page.status == Page.State.ERROR) {
 | 
			
		||||
            page.status = Page.State.QUEUE
 | 
			
		||||
        }
 | 
			
		||||
        queue.offer(PriorityPage(page, 2))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Data class used to keep ordering of pages in order to maintain priority.
 | 
			
		||||
     */
 | 
			
		||||
    private class PriorityPage(
 | 
			
		||||
        val page: ReaderPage,
 | 
			
		||||
        val priority: Int,
 | 
			
		||||
    ) : Comparable<PriorityPage> {
 | 
			
		||||
        companion object {
 | 
			
		||||
            private val idGenerator = AtomicInteger()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private val identifier = idGenerator.incrementAndGet()
 | 
			
		||||
 | 
			
		||||
        override fun compareTo(other: PriorityPage): Int {
 | 
			
		||||
            val p = other.priority.compareTo(priority)
 | 
			
		||||
            return if (p != 0) p else identifier.compareTo(other.identifier)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads the page, retrieving the image URL and downloading the image if necessary.
 | 
			
		||||
     * Downloaded images are stored in the chapter cache.
 | 
			
		||||
@@ -214,3 +195,22 @@ class HttpPageLoader(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Data class used to keep ordering of pages in order to maintain priority.
 | 
			
		||||
 */
 | 
			
		||||
private class PriorityPage(
 | 
			
		||||
    val page: ReaderPage,
 | 
			
		||||
    val priority: Int,
 | 
			
		||||
) : Comparable<PriorityPage> {
 | 
			
		||||
    companion object {
 | 
			
		||||
        private val idGenerator = AtomicInteger()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val identifier = idGenerator.incrementAndGet()
 | 
			
		||||
 | 
			
		||||
    override fun compareTo(other: PriorityPage): Int {
 | 
			
		||||
        val p = other.priority.compareTo(priority)
 | 
			
		||||
        return if (p != 0) p else identifier.compareTo(other.identifier)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,14 +15,7 @@ abstract class PageLoader {
 | 
			
		||||
    var isRecycled = false
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recycles this loader. Implementations must override this method to clean up any active
 | 
			
		||||
     * resources.
 | 
			
		||||
     */
 | 
			
		||||
    @CallSuper
 | 
			
		||||
    open fun recycle() {
 | 
			
		||||
        isRecycled = true
 | 
			
		||||
    }
 | 
			
		||||
    abstract var isLocal: Boolean
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the list of pages of a chapter.
 | 
			
		||||
@@ -34,11 +27,20 @@ abstract class PageLoader {
 | 
			
		||||
     * Progress of the page loading should be followed via [page.statusFlow].
 | 
			
		||||
     * [loadPage] is not currently guaranteed to complete, so it should be launched asynchronously.
 | 
			
		||||
     */
 | 
			
		||||
    abstract suspend fun loadPage(page: ReaderPage)
 | 
			
		||||
    open suspend fun loadPage(page: ReaderPage) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retries the given [page] in case it failed to load. This method only makes sense when an
 | 
			
		||||
     * online source is used.
 | 
			
		||||
     */
 | 
			
		||||
    open fun retryPage(page: ReaderPage) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recycles this loader. Implementations must override this method to clean up any active
 | 
			
		||||
     * resources.
 | 
			
		||||
     */
 | 
			
		||||
    @CallSuper
 | 
			
		||||
    open fun recycle() {
 | 
			
		||||
        isRecycled = true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,34 +15,20 @@ import java.util.concurrent.Executors
 | 
			
		||||
/**
 | 
			
		||||
 * Loader used to load a chapter from a .rar or .cbr file.
 | 
			
		||||
 */
 | 
			
		||||
class RarPageLoader(file: File) : PageLoader() {
 | 
			
		||||
internal class RarPageLoader(file: File) : PageLoader() {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The rar archive to load pages from.
 | 
			
		||||
     */
 | 
			
		||||
    private val archive = Archive(file)
 | 
			
		||||
    private val rar = Archive(file)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pool for copying compressed files to an input stream.
 | 
			
		||||
     */
 | 
			
		||||
    private val pool = Executors.newFixedThreadPool(1)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recycles this loader and the open archive.
 | 
			
		||||
     */
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        archive.close()
 | 
			
		||||
        pool.shutdown()
 | 
			
		||||
    }
 | 
			
		||||
    override var isLocal: Boolean = true
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns an RxJava Single containing the pages found on this rar archive ordered with a natural
 | 
			
		||||
     * comparator.
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun getPages(): List<ReaderPage> {
 | 
			
		||||
        return archive.fileHeaders.asSequence()
 | 
			
		||||
            .filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { archive.getInputStream(it) } }
 | 
			
		||||
        return rar.fileHeaders.asSequence()
 | 
			
		||||
            .filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { rar.getInputStream(it) } }
 | 
			
		||||
            .sortedWith { f1, f2 -> f1.fileName.compareToCaseInsensitiveNaturalOrder(f2.fileName) }
 | 
			
		||||
            .mapIndexed { i, header ->
 | 
			
		||||
                ReaderPage(i).apply {
 | 
			
		||||
@@ -53,13 +39,16 @@ class RarPageLoader(file: File) : PageLoader() {
 | 
			
		||||
            .toList()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * No additional action required to load the page
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun loadPage(page: ReaderPage) {
 | 
			
		||||
        check(!isRecycled)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        rar.close()
 | 
			
		||||
        pool.shutdown()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns an input stream for the given [header].
 | 
			
		||||
     */
 | 
			
		||||
@@ -69,7 +58,7 @@ class RarPageLoader(file: File) : PageLoader() {
 | 
			
		||||
        pool.execute {
 | 
			
		||||
            try {
 | 
			
		||||
                pipeOut.use {
 | 
			
		||||
                    archive.extractFile(header, it)
 | 
			
		||||
                    rar.extractFile(header, it)
 | 
			
		||||
                }
 | 
			
		||||
            } catch (e: Exception) {
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -12,28 +12,16 @@ import java.util.zip.ZipFile
 | 
			
		||||
/**
 | 
			
		||||
 * Loader used to load a chapter from a .zip or .cbz file.
 | 
			
		||||
 */
 | 
			
		||||
class ZipPageLoader(file: File) : PageLoader() {
 | 
			
		||||
internal class ZipPageLoader(file: File) : PageLoader() {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The zip file to load pages from.
 | 
			
		||||
     */
 | 
			
		||||
    private val zip = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
 | 
			
		||||
        ZipFile(file, StandardCharsets.ISO_8859_1)
 | 
			
		||||
    } else {
 | 
			
		||||
        ZipFile(file)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recycles this loader and the open zip.
 | 
			
		||||
     */
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        zip.close()
 | 
			
		||||
    }
 | 
			
		||||
    override var isLocal: Boolean = true
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the pages found on this zip archive ordered with a natural comparator.
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun getPages(): List<ReaderPage> {
 | 
			
		||||
        return zip.entries().asSequence()
 | 
			
		||||
            .filter { !it.isDirectory && ImageUtil.isImage(it.name) { zip.getInputStream(it) } }
 | 
			
		||||
@@ -47,10 +35,12 @@ class ZipPageLoader(file: File) : PageLoader() {
 | 
			
		||||
            .toList()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * No additional action required to load the page
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun loadPage(page: ReaderPage) {
 | 
			
		||||
        check(!isRecycled)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun recycle() {
 | 
			
		||||
        super.recycle()
 | 
			
		||||
        zip.close()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user