我正在遵循this个文档,并试图在我的应用程序中实现数据存储首选项,但我在做这件事上遇到了麻烦.

我有下面的代码,错误在三行:

import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.example.mymentalhealth.ui.theme.MyMentalHealthTheme
import kotlinx.coroutines.flow.Flow
import java.util.prefs.Preferences
import androidx.compose.runtime.getValue
import kotlinx.coroutines.flow.map

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings") // Error 1

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme {
                val ACCOUNT_TYPE = stringPreferencesKey("account_type")
                val accountTypeFlow: Flow<String> = context.dataStore.data // Error 2
                    .map { preferences -> // Error 3
                        preferences[ACCOUNT_TYPE] ?: ""
                    }

                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Text(text = "Hello, World")
                }
            }
        }
    }
}

错误1:属性委托必须具有‘getValue(Context,KProperty*&gt;)’方法.以下函数都不适用. Kotlin.Properties.ReadOnlyProperty中定义的getValue(Context,KProperty&lt;*&gt;)

错误2:无法使用提供的参数调用以下函数. context()在kotlin.coroutines.jvm.internal.CompletedContinuation中定义 context()在kotlinx.coroutines.flow.internal.NoOpContinuation中定义

错误3:无法推断此参数的类型.请明确说明.

除了使用字符串而不是int之外,我完全遵循文档.我也不确定如何访问和使用该变量(例如,在if语句中实现它).任何帮助都将不胜感激.谢谢.

Error 1: enter image description here

推荐答案

由于所有这些错误似乎都源于糟糕的导入语句,如果您在问题中也包含这些错误将会很有帮助. 下面将try 猜测可能出了什么问题.

虽然我不能复制您的Error 1,但这种错误通常可以通过添加import androidx.compose.runtime.getValue来修复.

Error 2似乎来自进口kotlinx.coroutines.flow.internal.NoOpContinuation.context或类似的东西.相反,你想要的是用applicationContext.dataStore.data取代context.dataStore.data.

Error 3将在您修复了前面的错误后,通过提供给您的快速修复程序来解决.你可能就差import kotlinx.coroutines.flow.map分了.


在回答经编辑的问题时:

Error 1似乎是从import java.util.prefs.Preferences开始的.应该是import androidx.datastore.preferences.core.Preferences.这也将修复"No value passed for parameter 'def'".

虽然我不能重现错误"Flow operator functions should not be invoked within composition"(或者它是一个警告?)这确实是一个值得关注的问题:根据流量的压力和要执行的操作,流量操作员可能非常耗时.这与composabe函数应该只执行轻度计算并快速终止的要求不兼容.常见的解决方案是将流移动到视图模型(数据存储流实际上属于层体系 struct 中更低的数据层).见https://developer.android.com/topic/architecture#data-layer).

Kotlin相关问答推荐

在Kotlin中将ClosedRange字符串转换为List?<>

计算值的Elvis算子

将带大括号和不带大括号的Lambda值赋给@Composable函数

从 Kotlin 的父类获取函数注解

Ktor 在 Heroku 上的 CORS 问题,但在本地没有

如何使用 Firebase 和 Kotlin 在文本 (Jetpack Compose) 中显示当前用户名?

如果带注释的成员未被特定块包围,则发出 IDE 警告

如何在 Android Jetpack Compose 中的画布上绘制一侧加厚的描边?

如何创建扩展函数isNullOrEmpty?

Jetpack compose 可滚动表格

从字符串列表构建字符串

将 Gradle 子元素与 Kotlin 多平台一起使用

是否可以在 kotlin 中嵌套数据类?

Hilt Activity 必须附加到 @AndroidEntryPoint 应用程序

什么是开放式property?为什么我不能将其设置器设为private私有?

有没有办法在数据类构建时转换属性的值?

Kotlin:使用Gradle进行增量编译

Tornadofx - 如何在每个实例上将参数传递给 Fragment

使用 Moshi/Retrofit2 访问深度嵌套的 JSON 数组

任务':app:kaptDebugKotlin'的Kotlin执行失败