This commit is contained in:
kunfei 2023-09-20 10:55:41 +08:00
parent fd6910afb0
commit c378af0541
7 changed files with 63 additions and 139 deletions

View File

@ -168,15 +168,15 @@ dependencies {
implementation('com.github.android:renderscript-intrinsics-replacement-toolkit:b6363490c3')
//androidX
implementation('androidx.core:core-ktx:1.10.1')
implementation('androidx.core:core-ktx:1.12.0')
implementation('androidx.appcompat:appcompat:1.6.1')
implementation('androidx.activity:activity-ktx:1.7.2')
implementation('androidx.fragment:fragment-ktx:1.6.1')
implementation('androidx.preference:preference-ktx:1.2.0')
implementation('androidx.preference:preference-ktx:1.2.1')
implementation('androidx.constraintlayout:constraintlayout:2.1.4')
implementation('androidx.swiperefreshlayout:swiperefreshlayout:1.1.0')
implementation('androidx.viewpager2:viewpager2:1.0.0')
implementation('androidx.webkit:webkit:1.7.0')
implementation('androidx.webkit:webkit:1.8.0')
//google
implementation('com.google.android.material:material:1.9.0')

View File

@ -89,7 +89,6 @@ object PreferKey {
const val syncBookProgress = "syncBookProgress"
const val cronet = "Cronet"
const val antiAlias = "antiAlias"
const val useLibArchive = "useLibArchive"
const val bitmapCacheSize = "bitmapCacheSize"
const val preDownloadNum = "preDownloadNum"
const val autoRefresh = "auto_refresh"

View File

@ -25,7 +25,6 @@ import splitties.init.appCtx
object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
val isCronet = appCtx.getPrefBoolean(PreferKey.cronet)
var useAntiAlias = appCtx.getPrefBoolean(PreferKey.antiAlias)
var useLibArchive = appCtx.getPrefBoolean(PreferKey.useLibArchive)
var userAgent: String = getPrefUserAgent()
var isEInkMode = appCtx.getPrefString(PreferKey.themeMode) == "3"
var clickActionTL = appCtx.getPrefInt(PreferKey.clickActionTL, 2)
@ -78,8 +77,6 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
PreferKey.antiAlias -> useAntiAlias = appCtx.getPrefBoolean(PreferKey.antiAlias)
PreferKey.useLibArchive -> useLibArchive =
appCtx.getPrefBoolean(PreferKey.useLibArchive)
}
}

View File

@ -5,7 +5,6 @@ import android.content.Intent
import android.net.Uri
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.github.junrar.exception.UnsupportedRarV5Exception
import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppLog
@ -299,13 +298,8 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
AppPattern.bookFileRegex.matches(it)
}
}.onError {
when (it) {
is UnsupportedRarV5Exception -> context.toastOnUi("暂不支持 rar v5 解压")
else -> {
AppLog.put("getArchiveEntriesName Error:\n${it.localizedMessage}", it)
context.toastOnUi("getArchiveEntriesName Error:\n${it.localizedMessage}")
}
}
AppLog.put("getArchiveEntriesName Error:\n${it.localizedMessage}", it)
context.toastOnUi("getArchiveEntriesName Error:\n${it.localizedMessage}")
}.onSuccess {
onSuccess.invoke(it)
}

View File

@ -3,11 +3,7 @@ package io.legado.app.utils
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import io.legado.app.constant.AppPattern.archiveFileRegex
import io.legado.app.help.config.AppConfig
import io.legado.app.utils.compress.LibArchiveUtils
import io.legado.app.utils.compress.RarUtils
import io.legado.app.utils.compress.SevenZipUtils
import io.legado.app.utils.compress.ZipUtils
import splitties.init.appCtx
import java.io.File
@ -65,49 +61,18 @@ object ArchiveUtils {
val workPathFileDoc = getCacheFolderFileDoc(name, path)
val workPath = workPathFileDoc.toString()
return if (AppConfig.useLibArchive) {
archiveFileDoc.openReadPfd().getOrThrow().use {
LibArchiveUtils.unArchive(it, File(workPath), filter)
}
} else {
archiveFileDoc.openInputStream().getOrThrow().use {
when {
name.endsWith(".zip", ignoreCase = true) -> ZipUtils.unZipToPath(
it,
workPath,
filter
)
name.endsWith(".rar", ignoreCase = true) -> RarUtils.unRarToPath(
it,
workPath,
filter
)
name.endsWith(".7z", ignoreCase = true) -> SevenZipUtils.un7zToPath(
it,
workPath,
filter
)
else -> throw IllegalArgumentException("Unexpected archive format")
}
}
return archiveFileDoc.openReadPfd().getOrThrow().use {
LibArchiveUtils.unArchive(it, File(workPath), filter)
}
}
/* 遍历目录获取文件名 */
fun getArchiveFilesName(fileUri: Uri, filter: ((String) -> Boolean)? = null): List<String> =
if (AppConfig.useLibArchive) {
getLibArchiveFilesName(FileDoc.fromUri(fileUri, false), filter)
} else {
getArchiveFilesName(FileDoc.fromUri(fileUri, false), filter)
}
getArchiveFilesName(FileDoc.fromUri(fileUri, false), filter)
fun getLibArchiveFilesName(
fun getArchiveFilesName(
fileDoc: FileDoc,
filter: ((String) -> Boolean)? = null
): List<String> {
@ -126,31 +91,6 @@ object ArchiveUtils {
}
fun getArchiveFilesName(
fileDoc: FileDoc,
filter: ((String) -> Boolean)? = null
): List<String> {
val name = fileDoc.name
checkAchieve(name)
return fileDoc.openInputStream().getOrThrow().use {
when {
name.endsWith(".rar", ignoreCase = true) -> {
RarUtils.getFilesName(it, filter)
}
name.endsWith(".zip", ignoreCase = true) -> {
ZipUtils.getFilesName(it, filter)
}
name.endsWith(".7z", ignoreCase = true) -> {
SevenZipUtils.getFilesName(it, filter)
}
else -> emptyList()
}
}
}
fun isArchive(name: String): Boolean {
return archiveFileRegex.matches(name)
}

View File

@ -13,6 +13,7 @@ import me.zhanghai.android.libarchive.ArchiveException
import java.io.File
import java.io.FileDescriptor
import java.io.IOException
import java.io.InputStream
import java.io.InterruptedIOException
import java.nio.ByteBuffer
import java.nio.channels.SeekableByteChannel
@ -23,52 +24,52 @@ import java.nio.charset.StandardCharsets
object LibArchiveUtils {
// @Throws(ArchiveException::class)
// fun openArchive(
// inputStream: InputStream,
// ): Long {
// val archive: Long = Archive.readNew()
// var successful = false
// try {
// Archive.setCharset(archive, StandardCharsets.UTF_8.name().toByteArray())
// Archive.readSupportFilterAll(archive)
// Archive.readSupportFormatAll(archive)
// Archive.readSetCallbackData(archive, null)
// val buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE)
// Archive.readSetReadCallback<Any?>(archive) { _, _ ->
// buffer.clear()
// val bytesRead = try {
// inputStream.read(buffer.array())
// } catch (e: IOException) {
// throw ArchiveException(Archive.ERRNO_FATAL, "InputStream.read", e)
// }
// if (bytesRead != -1) {
// buffer.limit(bytesRead)
// buffer
// } else {
// null
// }
// }
// Archive.readSetSkipCallback<Any?>(archive) { _, _, request ->
// try {
// inputStream.skip(request)
// } catch (e: IOException) {
// throw ArchiveException(Archive.ERRNO_FATAL, "InputStream.skip", e)
// }
// }
// Archive.readOpen1(archive)
// successful = true
// return archive
//
//
// } finally {
// if (!successful) {
// Archive.free(archive)
// }
// }
//
//
// }
@Throws(ArchiveException::class)
fun openArchive(
inputStream: InputStream,
): Long {
val archive: Long = Archive.readNew()
var successful = false
try {
Archive.setCharset(archive, StandardCharsets.UTF_8.name().toByteArray())
Archive.readSupportFilterAll(archive)
Archive.readSupportFormatAll(archive)
Archive.readSetCallbackData(archive, null)
val buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE)
Archive.readSetReadCallback<Any?>(archive) { _, _ ->
buffer.clear()
val bytesRead = try {
inputStream.read(buffer.array())
} catch (e: IOException) {
throw ArchiveException(Archive.ERRNO_FATAL, "InputStream.read", e)
}
if (bytesRead != -1) {
buffer.limit(bytesRead)
buffer
} else {
null
}
}
Archive.readSetSkipCallback<Any?>(archive) { _, _, request ->
try {
inputStream.skip(request)
} catch (e: IOException) {
throw ArchiveException(Archive.ERRNO_FATAL, "InputStream.skip", e)
}
}
Archive.readOpen1(archive)
successful = true
return archive
} finally {
if (!successful) {
Archive.free(archive)
}
}
}
@Throws(ArchiveException::class)
@ -208,7 +209,9 @@ object LibArchiveUtils {
}
/**
* 解压文件
*/
@Throws(NullPointerException::class, SecurityException::class)
fun unArchive(
pfd: ParcelFileDescriptor,
@ -218,14 +221,16 @@ object LibArchiveUtils {
return unArchive(openArchive(pfd), destDir, filter)
}
/**
* 解压
*/
@Throws(NullPointerException::class, SecurityException::class)
private fun unArchive(
archive: Long,
destDir: File?,
filter: ((String) -> Boolean)? = null
): List<File> {
destDir ?: throw NullPointerException("路径不能为空")
destDir ?: throw NullPointerException("路径不能为空")
val files = arrayListOf<File>()
@ -275,13 +280,8 @@ object LibArchiveUtils {
Archive.free(archive)
}
return files
}
fun getFilesName(pfd: ParcelFileDescriptor, filter: ((String) -> Boolean)?): List<String> {

View File

@ -98,12 +98,6 @@
android:summary="@string/pref_cronet_summary"
android:title="Cronet" />
<io.legado.app.lib.prefs.SwitchPreference
android:defaultValue="false"
android:key="useLibArchive"
android:summary="@string/pref_use_lib_archive_summary"
android:title="@string/use_lib_archive" />
<io.legado.app.lib.prefs.SwitchPreference
android:defaultValue="false"
android:key="antiAlias"