Reputation: 57
I'm following this documentation and attempting to implement DataStore preferences in my app, but I'm having trouble doing so.
I have the following code, and errors in three lines:
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")
}
}
}
}
}
Error 1: Property delegate must have a 'getValue(Context, KProperty*>)' method. None of the following functions are suitable. getValue(Context, KProperty<*>) defined in kotlin.properties.ReadOnlyProperty
Error 2: None of the following functions can be called with the arguments supplied. context() defined in kotlin.coroutines.jvm.internal.CompletedContinuation context() defined in kotlinx.coroutines.flow.internal.NoOpContinuation
Error 3: Cannot infer a type for this parameter. Please specify it explicitly.
I'm following the documentation exactly except for using a string instead of an int. I'm also unsure how to access and use the variable (for example implementing it in an if statement). Any help would be greatly appreciated. Thank you.
Upvotes: 1
Views: 613
Reputation: 15330
Since all of these errors seem to stem from bad import statements, it would have been helpful if you included those in your question as well. The following tries to guess what probably went wrong.
Although I cannot reproduce your Error 1, errors of this kind can usually be fixed by adding import androidx.compose.runtime.getValue
.
Error 2 seems to come from importing kotlinx.coroutines.flow.internal.NoOpContinuation.context
or something similar. What you want instead is to replace context.dataStore.data
with applicationContext.dataStore.data
.
Error 3 will be solved by the quick fix offered to you after you've fixed the previous errors. You are probably just missing import kotlinx.coroutines.flow.map
.
In response to the edited question:
Error 1 seems to originate from import java.util.prefs.Preferences
. It should be import androidx.datastore.preferences.core.Preferences
instead. This will also fix "No value passed for parameter 'def'".
Although I cannot reproduce the error "Flow operator functions should not be invoked within composition" (or is it a warning?) that really is a point of concern: Flow operators can, depending on the pressure of the flow and the operation to be performed, quite time consuming. That is incompatible with the requirement that composabe functions should only perform light calculations and terminate quickly. The common solution is to move the flow to a view model (the data store flow actually belongs even further down in the layer architecture, in the data layer. Also see https://developer.android.com/topic/architecture#data-layer).
Upvotes: 1