KMP Compose 多平台数据存储不适用于 JVM 版本构建

问题描述 投票:0回答:1

我正在开发一个以 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")
    }
}
jvm desktop-application kotlin-multiplatform compose-multiplatform android-jetpack-datastore
1个回答
0
投票

似乎谷歌问题跟踪器的解决方案有效:

nativeDistributions{
            targetFormats(TargetFormat.Msi, TargetFormat.Deb)
            modules("jdk.unsupported")
            modules("jdk.unsupported.desktop")            
}

https://issuetracker.google.com/issues/280205600

© www.soinside.com 2019 - 2024. All rights reserved.