安卓ComposeUI:创建一个本地保存数据

书接上回:安卓ComposeUI:创建一个变量-CSDN博客

ViewModel是管理Activity的数据,即应用正在使用的数据,如果应用重启,ViewModel的数据就会丢失,这时候就需要本地化,或远程化的数据解决方案。

一、安卓的数据保存方案

1、remember + mutableState。数据的生存周期在变量创建的那个Compose组件上面。

2、ViewModel + mutableState。数据的生存周期在活动的应用上面,比如竖屏变横屏不会销毁数据。

3、DataStore + ViewModel + mutableState。数据的生存周期在应用本地,重启应用不会销毁数据,删除应用会销毁数据。

4、远程数据方案 + ViewModel + mutableState。数据的生存周期在远程服务器,删除应用也不会销毁数据,销毁服务器的数据,才会真正销毁数据。

一个应用的数据多种多样,根据数据的存活周期选择把数据放在对应层级是更好的选择。比如Compose组件自身的状态信息只要放在remember层级即可,不需要持久化的数据放在ViewModel中即可。

二、DataStore

1、导入依赖

Kotlin 复制代码
implementation("androidx.datastore:datastore-preferences:1.2.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0")

// implementation(libs.androidx.datastore.preferences)
// implementation(libs.androidx.lifecycle.viewmodel.compose)

可以从maven仓库中获取到具体版本:https://mvnrepository.com/artifact/androidx.datastore

2、编写代码

Kotlin 复制代码
import android.util.Log

// 1.定义基础类
class AAA(val str: String = "hello") {

    fun speek(name: String) {
        Log.e("AAA", str + " " + name)
    }
}


import android.app.Application
import android.content.Context
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

// 2.ViewModel。
// 创建全局dataStore
private val Context.dataStore by preferencesDataStore("app_datastore")

class AppViewModel(app: Application) : AndroidViewModel(app) {
    private val dataStore = app.dataStore

    var aaa by mutableStateOf(AAA())
    private val dataKey = stringPreferencesKey("aaa")

    init {
        viewModelScope.launch {
            // 读数据
            dataStore.data.collect { preferences ->
                val a = preferences[dataKey] ?: ""
                aaa = AAA(a)
            }
        }
    }

    fun edit(newValue: String) {
        // aaa变量是针对mutableState<AAA>类进行委托,需要使用AAA类进行赋值,不能aaa.str = newValue
        aaa = AAA(newValue)
        viewModelScope.launch {
            dataStore.edit { preferences ->
                preferences[dataKey] = newValue
            }
        }
    }
}

// 3.使用datastore+viewModel
val vm: AppViewModel = viewModel()
            TestTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Column(
                        Modifier
                            .fillMaxSize()
                            .padding(innerPadding)
                    ) {
                        Spacer(Modifier.padding(vertical = 40.dp))
                        Text(
                            text = vm.aaa.str
                        )
                        Text(
                            text = "world!"
                        )
                        Button(
                            onClick = {
                                if(vm.aaa.str != "hello"){
                                    vm.edit("hello")
                                }else{
                                    vm.edit("hi")
                                }
                            }
                        ) {
                            Text("切换")
                        }
                    }
                }
            }

当datastore和viewMode结合使用时,需要注意数据有两份,datastore存储一份,viewMode中还有一份,viewMode中的数据不更新则无法触发系统的刷新机制,datastore中的数据不更新则无法将数据持久化。

三、安卓数据方案的总结

1.对于datastore本地化数据解决方案,和远程数据解决方案来说,viewMode和mutableState也是存在的,remember则不需要。

2.对于viewModel来说,mutableState是存在的,remember不需要。

3.对于remember来说,mutableState是存在的。