我正在开发一个以 Android 和桌面为目标的 Kotlin 多平台/Compose 多平台应用程序。我想使用 DataStore 在本地存储一些数据,即用户的刷新令牌和一些其他信息。
我遵循了 Philipp Lackner 的教程,效果非常好。但是当我从发布版本安装该应用程序时,它在桌面版本上停止工作。通过一些测试,我发现这个问题是在使用DataStore的
.edit()
功能时出现的。它到达函数,执行其中的所有内容,但永远不会退出它。这并不是说它不存储我的数据或抛出错误。它只是永远不会从该方法返回。
我真的不明白为什么它可以在调试版本上运行,但不能在发布版本上运行。
有人在桌面上使用过带有 KMP 的 DataStore 吗?如果是这样,它在发布版本中是否有效?
我使用的代码:
我要保存的对象:
data class AuthInfo(
val accessToken: String,
val refreshToken: String,
val userId: String,
val email: String
) {
companion object {
fun getEmpty(): AuthInfo {
return AuthInfo("", "", "", "")
}
}
}
创建 DataStore 实例的方法:
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import okio.Path.Companion.toPath
fun createDataStore(producePath: () -> String): DataStore<Preferences> {
return PreferenceDataStoreFactory.createWithPath(
produceFile = { producePath().toPath() }
)
}
internal const val DATA_STORE_FILE_NAME = "prefs.preferences_pb"
我的桌面Koin模块:
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import org.koin.dsl.module
actual val platformDataModule = module {
single<DataStore<Preferences>> { createDataStore { DATA_STORE_FILE_NAME } }
}
使用它的班级:
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
class EncryptedSessionStorage(
private val preferences: DataStore<Preferences>
) {
private val preferencesFlow = preferences.data
override suspend fun get(): AuthInfo? {
return withContext(Dispatchers.IO) {
val json = preferencesFlow.first()[KEY_AUTH_INFO]
json?.let {
Json.decodeFromString<AuthInfoSerializable>(it).toAuthInfo()
}
}
}
override suspend fun set(info: AuthInfo?) {
withContext(Dispatchers.IO) {
if(info == null) {
preferences.edit {
it.minusAssign(KEY_AUTH_INFO)
}
return@withContext
}
val json = Json.encodeToString(info.toAuthInfoSerializable())
preferences.edit {
it[KEY_AUTH_INFO] = json
// It executes code all the way to here
}
// Then never gets here
}
}
companion object {
private val KEY_AUTH_INFO = stringPreferencesKey("KEY_AUTH_INFO")
}
}
似乎谷歌问题跟踪器的解决方案有效:
nativeDistributions{
targetFormats(TargetFormat.Msi, TargetFormat.Deb)
modules("jdk.unsupported")
modules("jdk.unsupported.desktop")
}