This commit is contained in:
Horis
2024-08-17 20:59:31 +08:00
parent 7d006aa1c7
commit 9b93baa122
2 changed files with 48 additions and 58 deletions
@@ -40,6 +40,8 @@ object Backup {
}
val zipFilePath = "${appCtx.externalFiles.absolutePath}${File.separator}tmp_backup.zip"
private const val TAG = "Backup"
private val mutex = Mutex()
private val backupFileNames by lazy {
@@ -102,7 +104,16 @@ object Backup {
}
}
suspend fun backup(context: Context, path: String?) {
suspend fun backupLocked(context: Context, path: String?) {
mutex.withLock {
withContext(IO) {
backup(context, path)
}
}
}
private suspend fun backup(context: Context, path: String?) {
LogUtils.d(TAG, "开始备份 path:$path")
LocalConfig.lastBackup = System.currentTimeMillis()
val aes = BackupAES()
FileUtils.delete(backupPath)
@@ -216,14 +227,14 @@ object Backup {
coroutineContext.ensureActive()
withContext(IO) {
if (list.isNotEmpty()) {
AppLog.put("阅读备份 $fileName 列表大小 ${list.size}")
LogUtils.d(TAG, "阅读备份 $fileName 列表大小 ${list.size}")
val file = FileUtils.createFileIfNotExist(path + File.separator + fileName)
file.outputStream().buffered().use {
GSON.writeToOutputStream(it, list)
}
AppLog.put("阅读备份 $fileName 写入大小 ${file.length()}")
LogUtils.d(TAG, "阅读备份 $fileName 写入大小 ${file.length()}")
} else {
AppLog.put("阅读备份 $fileName 列表为空")
LogUtils.d(TAG, "阅读备份 $fileName 列表为空")
}
}
}
@@ -12,6 +12,7 @@ import android.view.View
import androidx.core.view.MenuProvider
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
@@ -50,6 +51,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import splitties.init.appCtx
import kotlin.collections.set
@@ -77,25 +79,11 @@ class BackupConfigFragment : PreferenceFragment(),
result.uri?.let { uri ->
if (uri.isContentScheme()) {
AppConfig.backupPath = uri.toString()
Coroutine.async {
Backup.backup(appCtx, uri.toString())
}.onSuccess {
appCtx.toastOnUi(R.string.backup_success)
}.onError {
AppLog.put("备份出错\n${it.localizedMessage}", it)
appCtx.toastOnUi(getString(R.string.backup_fail, it.localizedMessage))
}
backup(uri.toString())
} else {
uri.path?.let { path ->
AppConfig.backupPath = path
Coroutine.async {
Backup.backup(appCtx, path)
}.onSuccess {
appCtx.toastOnUi(R.string.backup_success)
}.onError {
AppLog.put("备份出错\n${it.localizedMessage}", it)
appCtx.toastOnUi(getString(R.string.backup_fail, it.localizedMessage))
}
backup(path)
}
}
}
@@ -278,27 +266,7 @@ class BackupConfigFragment : PreferenceFragment(),
val uri = Uri.parse(backupPath)
val doc = DocumentFile.fromTreeUri(requireContext(), uri)
if (doc?.checkWrite() == true) {
waitDialog.setText("备份中…")
waitDialog.setOnCancelListener {
backupJob?.cancel()
}
waitDialog.show()
Coroutine.async {
backupJob = coroutineContext[Job]
Backup.backup(requireContext(), backupPath)
}.onSuccess {
appCtx.toastOnUi(R.string.backup_success)
}.onError {
AppLog.put("备份出错\n${it.localizedMessage}", it)
appCtx.toastOnUi(
appCtx.getString(
R.string.backup_fail,
it.localizedMessage
)
)
}.onFinally(Main) {
waitDialog.dismiss()
}
backup(backupPath)
} else {
backupDir.launch()
}
@@ -308,28 +276,39 @@ class BackupConfigFragment : PreferenceFragment(),
}
}
private fun backup(backupPath: String) {
waitDialog.setText("备份中…")
waitDialog.setOnCancelListener {
backupJob?.cancel()
}
waitDialog.show()
backupJob?.cancel()
backupJob = lifecycleScope.launch {
try {
Backup.backupLocked(requireContext(), backupPath)
appCtx.toastOnUi(R.string.backup_success)
} catch (e: Throwable) {
ensureActive()
AppLog.put("备份出错\n${e.localizedMessage}", e)
appCtx.toastOnUi(
appCtx.getString(
R.string.backup_fail,
e.localizedMessage
)
)
} finally {
ensureActive()
waitDialog.dismiss()
}
}
}
private fun backupUsePermission(path: String) {
PermissionsCompat.Builder()
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
waitDialog.setText("备份中…")
waitDialog.setOnCancelListener {
backupJob?.cancel()
}
waitDialog.show()
Coroutine.async {
backupJob = coroutineContext[Job]
AppConfig.backupPath = path
Backup.backup(requireContext(), path)
}.onSuccess {
appCtx.toastOnUi(R.string.backup_success)
}.onError {
AppLog.put("备份出错\n${it.localizedMessage}", it)
appCtx.toastOnUi(appCtx.getString(R.string.backup_fail, it.localizedMessage))
}.onFinally {
waitDialog.dismiss()
}
backup(path)
}
.request()
}