我目前正在尝试将简单数据(PIN 码和恢复电子邮件)保存到数据存储中。这样我的应用程序就知道启动时的行为方式。我决定创建一个数据存储类来处理整个应用程序中的数据存储。我确信由于 toast 消息,这些函数会在适当的时间被调用。主要问题是,尽管完成了引脚设置阶段并看到引脚已更新,但引脚将始终保留值“教程”。
当前问题解决:
LaunchActivity.kt
class LaunchActivity : AppCompatActivity() {
private val dataModel by viewModels<LaunchVModel>()
private var pin: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen().apply {
setKeepOnScreenCondition {
!dataModel.isReady.value
}
setOnExitAnimationListener {
// code removed for brevity
}
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if(pin == null) { // no pin option set, start w/ tutorial
replaceFragment(TutorialFragment())
}
else if(pin == "tutorial") { // user chose not to have a pin
switchActivity()
}
else { // user has a pin
replaceFragment(PasscodeFragment())
}
dataModel.pin.observe(this) { // update the pin
pin = dataModel.returnPin()
Toast.makeText(this, "Pin val in View Model...$pin", Toast.LENGTH_SHORT).show()
}
}
}
基本数据
class BasicData (context: Context) {
private val Context.dataStore : DataStore<Preferences> by preferencesDataStore(name = "LaunchSettings")
private val dataStore = context.dataStore
suspend fun set(key : String, given : String) {
val dataStoreKey = stringPreferencesKey(key)
dataStore.edit{ basics ->
basics[dataStoreKey] = given
}
}
suspend fun retrieve(key: String) : String? {
val dataStoreKey = stringPreferencesKey(key)
val preferences = dataStore.data.first()
return preferences[dataStoreKey]
}
}
视图模型
class LaunchVModel(application: Application): AndroidViewModel(application) {
// needed for the pause on splash (launch) animation
private val _isReady = MutableStateFlow(false)
val isReady = _isReady.asStateFlow()
private var dataStore = BasicData(application)
var pin = MutableLiveData<String>()
var email = MutableLiveData<String>()
var skip = MutableLiveData<String>()
// immediately execute the splash delay
init {
viewModelScope.launch {
var temp = dataStore.retrieve("pin")
if(temp != null) {
pin.value = temp!!
_isReady.value = true
}
else {
pin.value = "tutorial"
_isReady.value = true
}
}
}
fun returnPin() : String? {
return pin.value.toString()
}
fun data(item: String) {
viewModelScope.launch {
dataStore.set("pin", item)
pin.value = item
}
}
}
问题出在您的
dataStore.data.first()
方法中的 retrieve
。将方法更新为:
suspend fun retrieve(key: String) : String? {
val dataStoreKey = stringPreferencesKey(key)
return dataStore.data.map{
it[dataStoreKey]
}.firstOrNull()
}