添加Mutex互斥锁

This commit is contained in:
ocean 2025-09-08 12:06:00 +08:00
parent 1f664cd191
commit 86750a4429

View File

@ -13,6 +13,8 @@ import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
import com.all.pdfreader.pro.app.room.repository.PdfRepository import com.all.pdfreader.pro.app.room.repository.PdfRepository
import com.all.pdfreader.pro.app.util.FileUtils.isPdfEncrypted import com.all.pdfreader.pro.app.util.FileUtils.isPdfEncrypted
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@ -23,14 +25,14 @@ class PdfScanner(
) { ) {
private val TAG = "ocean-PdfScanner" private val TAG = "ocean-PdfScanner"
private val scanMutex = Mutex()
suspend fun scanAndLoadPdfFiles(isNeedFullScan: Boolean, callback: (Boolean) -> Unit = {}) { suspend fun scanAndLoadPdfFiles(isNeedFullScan: Boolean, callback: (Boolean) -> Unit = {}) {
if (!StoragePermissionHelper.hasBasicStoragePermission(context)) { if (!StoragePermissionHelper.hasBasicStoragePermission(context)) {
LogUtil.logDebug(TAG, "权限不足") LogUtil.logDebug(TAG, "权限不足")
callback.invoke(false) callback.invoke(false)
return return
} }
scanMutex.withLock {// 保证同一时间只有一次扫描
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
try { try {
val startScannerTime = System.currentTimeMillis() val startScannerTime = System.currentTimeMillis()
@ -47,10 +49,11 @@ class PdfScanner(
var updatedDoc = doc.copy() var updatedDoc = doc.copy()
// 修改时间 与 文件大小 // 修改时间 与 文件大小
if (file.lastModified() != doc.lastModified || file.length() != doc.fileSize) { if (file.lastModified() != doc.lastModified || file.length() != doc.fileSize) {
LogUtil.logDebug(TAG, "文件时间或者大小被修改 -> ${doc.fileName}") LogUtil.logDebug(
TAG, "文件时间或者大小被修改 -> ${doc.fileName}"
)
updatedDoc = updatedDoc.copy( updatedDoc = updatedDoc.copy(
lastModified = file.lastModified(), lastModified = file.lastModified(), fileSize = file.length()
fileSize = file.length()
) )
needUpdate = true needUpdate = true
} }
@ -65,7 +68,8 @@ class PdfScanner(
if (!currentIsPassword) { if (!currentIsPassword) {
val newThumbnail = generateThumbnail(context, file) val newThumbnail = generateThumbnail(context, file)
if (doc.thumbnailPath != newThumbnail) { if (doc.thumbnailPath != newThumbnail) {
updatedDoc = updatedDoc.copy(thumbnailPath = newThumbnail) updatedDoc =
updatedDoc.copy(thumbnailPath = newThumbnail)
} }
} else if (doc.thumbnailPath != null) { } else if (doc.thumbnailPath != null) {
updatedDoc = updatedDoc.copy(thumbnailPath = null) updatedDoc = updatedDoc.copy(thumbnailPath = null)
@ -90,7 +94,8 @@ class PdfScanner(
val mediaStoreFiles = FileUtils.scanPdfFilesFromMediaStore(context) val mediaStoreFiles = FileUtils.scanPdfFilesFromMediaStore(context)
LogUtil.logDebug(TAG, "📱MediaStore找到: ${mediaStoreFiles.size} 个PDF文件") LogUtil.logDebug(TAG, "📱MediaStore找到: ${mediaStoreFiles.size} 个PDF文件")
// 合并并去重 // 合并并去重
val allFiles = (privateFiles + mediaStoreFiles).distinctBy { it.absolutePath } val allFiles =
(privateFiles + mediaStoreFiles).distinctBy { it.absolutePath }
LogUtil.logDebug(TAG, "📊总计扫描到: ${allFiles.size} 个PDF文件") LogUtil.logDebug(TAG, "📊总计扫描到: ${allFiles.size} 个PDF文件")
// 处理每个PDF文件 // 处理每个PDF文件
allFiles.forEachIndexed { index, file -> allFiles.forEachIndexed { index, file ->
@ -104,7 +109,8 @@ class PdfScanner(
LogUtil.logDebug(TAG, "🔑文件哈希: $fileHash") LogUtil.logDebug(TAG, "🔑文件哈希: $fileHash")
if (fileHash != null) { if (fileHash != null) {
val existingDoc = pdfRepository.getDocumentByPath(file.absolutePath) val existingDoc =
pdfRepository.getDocumentByPath(file.absolutePath)
if (existingDoc == null) { if (existingDoc == null) {
LogUtil.logDebug( LogUtil.logDebug(
@ -159,7 +165,8 @@ class PdfScanner(
val currentIsPassword = isPdfEncrypted(file) val currentIsPassword = isPdfEncrypted(file)
if (existingDoc.isPassword != currentIsPassword) { if (existingDoc.isPassword != currentIsPassword) {
LogUtil.logDebug(TAG, "✅ 密码状态需要更新") LogUtil.logDebug(TAG, "✅ 密码状态需要更新")
updatedDoc = updatedDoc.copy(isPassword = currentIsPassword) updatedDoc =
updatedDoc.copy(isPassword = currentIsPassword)
needUpdate = true needUpdate = true
} }
@ -219,8 +226,7 @@ class PdfScanner(
// 计算扫描耗时 // 计算扫描耗时
val scannerTime = System.currentTimeMillis() - startScannerTime val scannerTime = System.currentTimeMillis() - startScannerTime
LogUtil.logDebug( LogUtil.logDebug(
TAG, TAG, "$string 本次扫描耗时: $scannerTime ms (${scannerTime / 1000.0} 秒)"
"$string 本次扫描耗时: $scannerTime ms (${scannerTime / 1000.0} 秒)"
) )
PDFReaderApplication.isNeedFullScan = false PDFReaderApplication.isNeedFullScan = false
callback.invoke(true) callback.invoke(true)
@ -230,6 +236,7 @@ class PdfScanner(
} }
} }
} }
}
fun shouldScan(): Boolean { fun shouldScan(): Boolean {
return ScanManager.shouldScan(context) return ScanManager.shouldScan(context)