当前位置: 首页 > news >正文

网站建设开发程序网站策划书的撰写流程是什么

网站建设开发程序,网站策划书的撰写流程是什么,0基础微信小程序开发教程,建设部网站投标保证金简介 首先,DataStore是Jetpack一部分,是一种数据存储解决方案。其次,DataStore使用协程及flow以异步、一致的方式实现数据的存储。最后是DataStore的实现,分为Preferences DataStore和Proto DataStore:Preferences Da…

简介

  • 首先,DataStore是Jetpack一部分,是一种数据存储解决方案。
  • 其次,DataStore使用协程及flow以异步、一致的方式实现数据的存储。
  • 最后是DataStore的实现,分为Preferences DataStore和Proto DataStore:
  • Preferences DataStore 类似于SharedPreferences,键值对存储,本篇的主要介绍。
  • Proto DataStore 将数据作为自定义数据类型的实例进行存储,基于Google protobuf实现。

DataStore和SharedPreferences(SP)

  • SP存在的问题:
  • 内存浪费问题,加载的数据会一直存在在内存中。
  • get方法可能会阻塞主线程。
  • apply方法虽然为异步,也可能会发生ANR。
  • SP也无法保证类型安全。
  • SP不支持跨进程。
  • DataStore的特点:
  • 基于协程和Flow实现,保证了主线程的安全性。
  • 以事务的方式进行处理,保证了操作的原子性、一致性、隔离性及持久性。
  • Preferences DataStore可以支持SP的迁移,保证数据的完整性。
  • 说明:
  • 此处只是列出SP存在的问题,并没有SP一无是处的的说法,DataStore在SP的基础上解决了不少的问题,但是也没有说SP存在的问题已经全部解决了。
  • 至少,DataStore在SP的基础上解决了如类型安全、阻塞导致anr等问题,确实这方面优于SP。

使用

Preferences DataStore

基本使用流程

引入

def dataStoreVersion = '1.0.0-beta01'
implementation "androidx.datastore:datastore-preferences:$dataStoreVersion"

创建DataStore

//指定DataStore的文件名
//对应最终件:/data/data/org.geekbang.aac/files/datastore/user_preferences.preferences_pb
private const val USER_PREFERENCES_NAME = "user_preferences"
//扩展属性DataStore,实际类型为DataStore<Preferences>
private val Context.dataStore by preferencesDataStore(
name = USER_PREFERENCES_NAME,//指定名称
produceMigrations = {context ->  //指定要恢复的sp文件,无需恢复可不写listOf(SharedPreferencesMigration(context, USER_PREFERENCES_NAME))
}
)

定义Key

val SORT_ORDER = stringPreferencesKey("sort_order")
val SHOW_COMPLETED = booleanPreferencesKey("show_completed")
//... 通过查看源码可以看到支持的其它数据类型

存储

//edit要在suspend函数中
override suspend fun updateShowCompleted(showCompleted: Boolean) {dataStore.edit { preferences ->//...这里可以做一些数据的逻辑处理preferences[SHOW_COMPLETED] = showCompleted// 整个tranform中的所有代码块被视为单个事务}
}

读取

override val userPreferencesFlow = dataStore.data.catch { exception ->if (exception is IOException) {//进行IO异常处理,确保能得到默认值Log.e(TAG, "Error reading preferences.", exception)emit(emptyPreferences())} else {throw exception}}.map { preferences ->//真正的获取存储的一个字段val sortOrder = SortOrder.valueOf(preferences[SORT_ORDER] ?: SortOrder.NONE.name)val showCompleted = preferences[SHOW_COMPLETED] ?: falseUserPreferences(showCompleted, sortOrder)}

使用总结

一个对应的preferences_pb文件对应一个.kt文件,里面包含了文件名定义,DataStore定义,Key定义,存取方法定义;例如:

//TaskConfigDataStore.kt
/*** 文件名
*/
private const val TASK_CONFIG_PREFERENCES_FILE_NAME = "task_config_pre"
​
/*** dataStore对象
*/
val Context.taskConfigDataStore : DataStore<Preferences> by preferencesDataStore(
name = TASK_CONFIG_PREFERENCES_FILE_NAME
)
​
/** Keys **/
val SHOW_COMPLETED = booleanPreferencesKey("show_completed")
val OPEN_COUNT = intPreferencesKey("open_count")
//other keys
​
​
/** 存取方法 **/
fun getShowCompleted(context: Context): Flow<Boolean>
= context.taskConfigDataStore.data.catch { e->if(e is IOException){emptyPreferences()}else{throw e}}.map { pre->pre[SHOW_COMPLETED] ?: false}
​
suspend fun setShowCompleted(context: Context,showComplete: Boolean){
context.taskConfigDataStore.edit { pre->pre[SHOW_COMPLETED] = showComplete
}
}
// other method

ProtoBuf DataStore

基本使用流程

接入protobuf,以最新的为准 详情信息可参考

protobuf-gradle-plugin

,想详细了解protobuf基础知识,可参考

Protobuf 终极教程

  • 在xxx.build中加入:
  plugins {//other...id "com.google.protobuf" version "0.8.16"}
  • dependencies
// protobuf
def protobufVersion = "3.10.0"
// 3.0.0后Android建议使用javalite
implementation  "com.google.protobuf:protobuf-javalite:$protobufVersion"
  • 增加protobuf 的块
protobuf {protoc {artifact = "com.google.protobuf:protoc:3.10.0"}
​generateProtoTasks {all().each { task ->task.builtins {java {option 'lite'}}}}
}
  • 在src/main/目录下建立proto文件,3.8.0以后自动识别此目录下的.proto文件

引入dataStore库

// dataStore
def dataStoreVersion = '1.0.0-beta01'
implementation  "androidx.datastore:datastore:$dataStoreVersion"

建立proto文件后,进行rebuild

syntax = "proto3";
option java_package = "org.geekbang.aac";
option java_multiple_files = true;
message UserPreferences {
bool show_completed = 1;
enum SortOrder {UNSPECIFIED = 0;NONE = 1;BY_DEADLINE = 2;BY_PRIORITY = 3;BY_DEADLINE_AND_PRIORITY = 4;
}
SortOrder sort_order = 2;
}

创建Serializer的实现,告诉框架如何读写,这个接口明确规定要有默认值,以便在尚未创建任何文件时使用,这是必要流程,基本是固定写法,用编译器生成的Java类对应api即可

object UserPreferencesSerializer : Serializer<UserPreferences> {override val defaultValue: UserPreferences = UserPreferences.getDefaultInstance()@Suppress("BlockingMethodInNonBlockingContext")override suspend fun readFrom(input: InputStream): UserPreferences {try {return UserPreferences.parseFrom(input)} catch (exception: InvalidProtocolBufferException) {throw CorruptionException("Cannot read proto.", exception)}}@Suppress("BlockingMethodInNonBlockingContext")override suspend fun writeTo(t: UserPreferences, output: OutputStream) = t.writeTo(output)
}

定义创建DataStore对象

//老的sp的文件名
private const val USER_PREFERENCES_NAME = "user_preferences"
//新的文件名,对应目录 /data/data/com.codelab.android.datastore/files/datastore/user_prefs.pb
private const val DATA_STORE_FILE_NAME = "user_prefs.pb"
//老的对应的key
private const val SORT_ORDER_KEY = "sort_order"
// Build the DataStore
private val Context.userPreferencesStore: DataStore<UserPreferences> by dataStore(fileName = DATA_STORE_FILE_NAME,serializer = UserPreferencesSerializer,produceMigrations = { context ->listOf(SharedPreferencesMigration(context,USER_PREFERENCES_NAME) { sharedPrefs: SharedPreferencesView, currentData: UserPreferences ->// 定义从SharedPreferences到UserPreference的映射if (currentData.sortOrder == SortOrder.UNSPECIFIED) {currentData.toBuilder().setSortOrder(SortOrder.valueOf(sharedPrefs.getString(SORT_ORDER_KEY, SortOrder.NONE.name)!!)).build()} else {currentData}})}
)

存储

//必须是挂起函数,决定其要在协程中使用
suspend fun updateShowCompleted(completed: Boolean) {
//Proto DataStore 提供了一个updateData() 函数,
//用于以事务方式更新存储的对象
//为您提供数据的当前状态,作为数据类型的一个实例,并在原子读-写-修改操作中以事务方式更新数据userPreferencesStore.updateData { currentPreferences ->//当前文件对应的对象currentPreferences.toBuilder().setShowCompleted(completed).build()//对当前对象进行修改}}

读取

val userPreferencesFlow: Flow<UserPreferences> = userPreferencesStore.data.catch { exception ->// dataStore.data throws an IOException when an error is encountered when reading > dataif (exception is IOException) {Log.e(TAG, "Error reading sort order preferences.", exception)emit(UserPreferences.getDefaultInstance())} else {throw exception}}
//单独获取时是阻塞的,在实际使用中建议是异步的,在Kotlin项目中可以使用协程异步实现
suspend fun getUserPreferencesFlowData() = userPreferencesFlow.first()

使用总结

这个是面向相对复杂的对象结构(例如用户信息的本地缓存)的场景下使用,一般以一个proto文件为单位,相关定义,方法做好整体分类即可。

DataStore的优势

  • DataStore 是基于 Flow 实现的,所以保证了在主线程的安全性
  • 以事务方式处理更新数据,事务有四大特性(原子性、一致性、 隔离性、持久性)
  • 没有 apply() 和 commit() 等等数据持久的方法
  • 自动完成 SharedPreferences 迁移到 DataStore,保证数据一致性,不会造成数据损坏
  • 可以监听到操作成功或者失败结果
http://www.yayakq.cn/news/293444/

相关文章:

  • 音乐网站首页设计网站产品介绍长图哪个软件做的
  • ui设计网站建设是什么设计一个网站先做哪些构造
  • 行政单位门户网站建设方案网站前台与后台建设的先后次序
  • 大型门户网站制作教程青岛网站制作方案
  • 阿里云服务器添加网站中国黄金集团j建设公司网站
  • 个人网页制作在线广州网站优化排名
  • 海南住房和城乡建设网站广西建设安全员证查询网站
  • 毕业网站设计常用的系统开发方法有哪些
  • 免费做名片的网站免费wordpress主题下载地址
  • 做公司网站的步骤seo 网站文案模板
  • 国际贸易电子商务网站建设流程网站服务器ip地址在哪里看
  • 网站广告动态图怎么做2017如何免费制作网站
  • 做js题目的网站绵阳建设局网站皱劲松
  • 深圳定制网站制作报价企业网站公告怎么做
  • 网站备案 公司注销有没有教做韩餐的网站
  • wordpress 做大型网站吗网页游戏排行榜前十名超清画面
  • 网站后台 刷新海外 网站 推广
  • 团购网站短信平台广告策划活动公司
  • 广州市手机网站建设服务机构大连今年大项目建设
  • 南宁网站建设制作短视频推广渠道
  • 深圳 网站开发可以做c oj的网站
  • 漳州城乡和建设局网站如何为网站做seo体检
  • 网站推广软文代发淄博网站设计
  • elision豪华级创意企业中文wordpress主题整站修改wordpress浏览器小图标
  • 购物网站建设工作流程网站建设好与管理在哪就业
  • 高端网站设计合肥网站建设wordpress 教程网
  • 做网站苏州小规模网站开发税率
  • 海口企业做网站设计更改网站文章上传时间
  • 坡头网站开发公司商业网站源码
  • 一个网站完整的html代码商旅通官网app