android - 为什么我在尝试执行备份时收到“代理错误”?
问题描述
我正在为我的 Android 应用程序实施备份系统。我正在使用自定义 BackupAgentHelper 来备份共享首选项和数据库文件:
class CustomAgent : BackupAgentHelper() {
val DB_NAME = "notesDB"
val DB_BACKUP_KEY = "dbBackup"
val SHARED_PREFS_KEY = "prefsBackup"
override fun onCreate() {
super.onCreate()
//Backup note's database file
val dbHelper = FileBackupHelper(this, DB_NAME)
addHelper(DB_BACKUP_KEY, dbHelper)
//Backup SharedPreferences
val prefHelper = SharedPreferencesBackupHelper(this)
addHelper(SHARED_PREFS_KEY, prefHelper)
}
override fun onBackup(
oldState: ParcelFileDescriptor?,
data: BackupDataOutput?,
newState: ParcelFileDescriptor?
) {
super.onBackup(oldState, data, newState)
Toast.makeText(this, "Performing backup...", Toast.LENGTH_SHORT).show()
}
override fun onRestore(
data: BackupDataInput?,
appVersionCode: Int,
newState: ParcelFileDescriptor?
) {
Toast.makeText(this, "Restoring...", Toast.LENGTH_SHORT).show()
super.onRestore(data, appVersionCode, newState)
}
override fun onQuotaExceeded(backupDataBytes: Long, quotaBytes: Long) {
Toast.makeText(this, "Failed backup: The size is too big.", Toast.LENGTH_SHORT).show()
super.onQuotaExceeded(backupDataBytes, quotaBytes)
}
override fun getFilesDir(): File {
val path = getDatabasePath(DB_NAME)
return path.parentFile
}
}
我想显示一条 Toast 消息,让用户知道备份正在运行,并在有任何问题时通知他们。但是,如果我使用 Toast 消息运行应用程序,并执行以下 adb 命令来请求备份...
adb -s emulator-5554 shell bmgr backupnow com.byteseb.grafobook
我得到这个输出:
为 1 个请求的包运行增量备份。
打包@pm@ 结果:成功
使用结果打包 com.byteseb.grafobook:代理错误
备份完成,结果:成功
并且没有显示 Toast 消息。
但是,如果我删除 Toast 消息行或用 println() 函数替换它们并执行相同的命令,我将得到以下输出:
为 1 个请求的包运行增量备份。
打包@pm@ 结果:成功
使用结果打包 com.byteseb.grafobook:成功
备份完成,结果:成功
为什么会发生此错误?如果不允许我显示 Toast,我还能做些什么来通知用户有关备份的信息?
解决方案
正如@MikeM 所说,发生这种情况是因为我正在从非 UI 线程执行代码。
我通过使用处理程序解决了这个问题,这个处理程序负责从 UI 线程运行代码:
override fun onBackup(
oldState: ParcelFileDescriptor?,
data: BackupDataOutput?,
newState: ParcelFileDescriptor?
) {
super.onBackup(oldState, data, newState)
val handler = Handler(Looper.getMainLooper())
val runnable = Runnable {
Toast.makeText(this, "Performing backup...", Toast.LENGTH_SHORT).show()
}
handler.post(runnable)
}
推荐阅读
- python - 根据条件替换列中的值
- r - 在ggplot2中连接线图的平均点
- python - Sparse2Corpus 中的documents_columns 参数有什么作用?
- sql-server - 如何比较 SQL Server 中 2 个不同表中的单元格中的数据?
- html - 端口转发后,我的文件可以通过 Internet 访问吗?
- spring - 使用 ReactiveCrudRepository 的多租户
- reactjs - 为什么 react 组件返回多个元素?
- php - 在 Laravel 的 iframe 的 src 中,HTTP 被更改为 HTTPS
- cmake - CMAKE_PREFIX_PATH 和 CMAKE_MODULE_PATH 都是空的,find_package 仍然有效
- javascript - 为什么我的 onscroll 功能在元素完全滚动之前停止?