当前位置:   article > 正文

Android笔记(十九):JetPack DataStore 之 Preferences DataStore_android datastore

android datastore

Jetpack DataStore 是一种数据存储解决方案,主要适用于小型数据的处理。它可以通过协议缓冲区存储键值对或类型化对象。DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据。DataStore有两种实现方式(1)Preferences DataStore 和 (2)Proto DataStore.

Preferences DataStore利用键值对实现对简单数据的读写存储。这种方式不需要预定架构,也不确保类型安全。

一、增加依赖库

要使用Preferences DataStore需要在项目模块的build.gradle.kt中增加如下的依赖库:

dependencies {
        ...
	    implementation("androidx.datastore:datastore-preferences:1.0.0")

        // 可选项-用于RxJava2支持
        implementation("androidx.datastore:datastore-preferences-rxjava2:1.0.0")

        // 可选项-用于 RxJava3 支持
        implementation("androidx.datastore:datastore-preferences-rxjava3:1.0.0")
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

下面通过一个简单的实例来了解Perference DataStore的应用。在这个例子中, 记录当前账号访问的次数。运行效果如下图所示。
在这里插入图片描述

二、定义一个实用类DatastoreUtils

利用该实用类DatastoreUtils实现对数据的读写操作。

class DataStoreUtils(val context:Context){
    //利用preferenceDataStore创建委托来创建Preferences DataStore实例
    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name="settings")
    //定义关键字email
    private val EMAIL = stringPreferencesKey("email")
    //定义关键字counter
    private val COUNTER = intPreferencesKey("counter")
    //设置关键字对应存储的email值保存在Flow中
    val emailFlow: Flow<String> = context.dataStore.data.map {
        it[EMAIL]?:""
    }
    //设置关键字对应存储的counter值保存在Flow中
    val counterFlow:Flow<Int> = context.dataStore.data.map{
        it[COUNTER]?:0
    }

    /**
     * 定义挂起函数
     * 设置email账号对应访问应用的次数
     */
    suspend fun storeData(email:String){
        context.dataStore.edit{settings:MutablePreferences->
            val storedEmailValue = settings[EMAIL]?:""
            val storedCounterValue = settings[COUNTER]?:0

            if(storedEmailValue.isBlank()||storedEmailValue!=email) {
                settings[EMAIL] = email
                settings[COUNTER]= 1
            }else{
                settings[COUNTER] = storedCounterValue+1
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

三 、定义界面MainScreen

在界面的组合函数MainScreen中调用DatastoreUtils实现对数据的读取操作。代码如下:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(dataStoreUtils: DataStoreUtils,modifier:Modifier = Modifier){
    val context = LocalContext.current

    var emailInput by remember{mutableStateOf("guest@eyes.com")}
    var rememberInput by remember{mutableStateOf(false)}
    var content by remember{mutableStateOf("")}

    val scope = rememberCoroutineScope()
    //读取数据
    LaunchedEffect(Unit){
            dataStoreUtils.counterFlow.collect{c:Int->
                dataStoreUtils.emailFlow.collect{account:String->
                    content = "账号:${account}访问次数是:${c}次"
                }
            }
    }
    Column{
        TextField(modifier = Modifier.fillMaxWidth(),
            value = emailInput,
            onValueChange = {it:String->
                emailInput = it
            },
            label ={Text("输入账号")},
            leadingIcon = {
                Icon(imageVector = Icons.Filled.Email,contentDescription = "账号")
            }
        )
        Row{
            Checkbox(checked = rememberInput, onCheckedChange ={
                 rememberInput = it
                 if(rememberInput)
                 scope.launch {
                     //写入数据
                     dataStoreUtils.storeData(emailInput)
                 }
            })
            Text("记住账号")
        }

        if(!emailInput.isBlank())
            Text(text = content ,fontSize=20.sp)

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

说明:因为在应用中,活动界面中只能有一个Preferences DataStore的活动实例,因此在上述代码中对DataStore处理的DatastoreUtils实用类通过传参传递过来。也可以考虑使用单例模式,在整个应用中只有一个处理DataStore的对象实例。

四、定义主活动MainActivity

在主活动中调用主界面。代码如下:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ForCourseTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    MainScreen(DataStoreUtils(this))
                }
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

启动应用,可以在Device Explorer中的data->data目录下找到应用包,在它的下级目录files->datastore的settings.preferences_pb文件中保存键值对数据。如下图所示:
在这里插入图片描述
图1 模拟器中存放的键值对数据

参考文献

DataStore
https://developer.android.google.cn/topic/libraries/architecture/datastore?hl=zh-cn

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/309349?site
推荐阅读
相关标签
  

闽ICP备14008679号