HarmonyOS基础技术赋能之轻量级数据库Preferencens 原创 精华

软通张二龙
发布于 2021-8-23 15:05
浏览
16收藏

HarmonyOS基础技术赋能之轻量级数据库Preferencens-鸿蒙开发者社区

引言
轻量级数据存储适用于对Key-Value结构的数据进行存取和持久化操作。主要用于保存应用的一些常用配置,并不适合存储大量数据和频繁改变数据的场景。用户的数据保存在文件中,可以持久化的存储在设备上。需要注意的是用户访问的实例包含文件所有数据,并一直加载在设备的内存中,并通过轻量级数据存储的API完成数据操作。

功能介绍
轻量级数据存储向本地应用提供的API支持本地应用读写数据及观察数据变化。数据存储形式为键值对,键的类型为字符串型(String),值的存储数据类型包括整型(int)、字符串型(String)、布尔型(boolean)、浮点型(float)、长整型(long)、字符串型Set集合(Set<String>)。

开发指南

1. 创建Preferences实例。

// context为上下文对象,PREFERENCE_FILE_NAME为轻量级数据库文件名,String类型,可以自定义
databaseHelper = new DatabaseHelper(context);
preferences = databaseHelper.getPreferences(PREFERENCE_FILE_NAME);

2. 将数据写入指定文件。

// preferences.putString()为存入String类型的数据
preferences.putString(String key, String value);
// flush()为异步持久化数据;flushSync()为同步持久化数据
preferences.flush()/preferences.flushSync();

3.从指定文件读取数据。

//读取时传入的key, 要与写入时传入的key一致,才能获取对应数据,第二个参数为默认值。
  preferences.getString(String key, String default)

4. 开发者可以向Preferences实例注册观察者,观察数据更新变化。

private class PreferencesObserverImpl implements Preferences.PreferencesObserver {
   
    @Override    
    public void onChange(Preferences preferences, String key) {
        if ("key".equals(key)) {
           HiLog.info(LABLE, "Change Received:[key=value]");        
        }    
    }
}


// 向preferences实例注册观察者
PreferencesObserverImpl observer = new PreferencesObserverImpl();
preferences.registerObserver(observer);
// 修改数据后,observer的onChange方法会被回调
// 向preferences实例注销观察者
preferences.unRegisterObserver(observer);

源码如下:

1.PreferenceUtils

public class PreferenceUtils {

  private static String PREFERENCE_FILE_NAME = "prefrence_file";
  private static Preferences preferences;
  private static DatabaseHelper databaseHelper;
  private static PreferencesObserver mPreferencesObserver;

  private static void initPreference(Context context){
    if(databaseHelper==null){
      databaseHelper = new DatabaseHelper(context);
    }
    if(preferences==null){
      preferences = databaseHelper.getPreferences(PREFERENCE_FILE_NAME);
    }

  }

  //存放、获取时传入的context必须是同一个context,否则存入的数据无法获取
  public static void putString(Context context, String key, String value) {
    initPreference(context);
    preferences.putString(key, value);
    preferences.flush();
  }

  /**
   * @param context 上下文
   * @param key  键
   * @return 获取的String 默认值为:null
   */
  public static String getString(Context context, String key) {
    initPreference(context);
    return preferences.getString(key, null);
  }


  public static void putInt(Context context, String key, int value) {
    initPreference(context);
    preferences.putInt(key, value);
    preferences.flush();
  }

  /**
   * @param context 上下文
   * @param key 键
   * @return 获取int的默认值为:-1
   */
  public static int getInt(Context context, String key) {
    initPreference(context);
    return preferences.getInt(key, -1);
  }


  public static void putLong(Context context, String key, long value) {
    initPreference(context);
    preferences.putLong(key, value);
    preferences.flush();
  }

  /**
   * @param context 上下文
   * @param key  键
   * @return 获取long的默认值为:-1
   */
  public static long getLong(Context context, String key) {
    initPreference(context);
    return preferences.getLong(key, -1L);
  }


  public static void putBoolean(Context context, String key, boolean value) {
    initPreference(context);
    preferences.putBoolean(key, value);
    preferences.flush();
  }

  /**
   * @param context  上下文
   * @param key  键
   * @return 获取boolean的默认值为:false
   */
  public static boolean getBoolean(Context context, String key) {
    initPreference(context);
    return preferences.getBoolean(key, false);
  }


  public static void putFloat(Context context, String key, float value) {
    initPreference(context);
    preferences.putFloat(key, value);
    preferences.flush();
  }

  /**
   * @param context 上下文
   * @param key   键
   * @return 获取float的默认值为:0.0
   */
  public static float getFloat(Context context, String key) {
    initPreference(context);
    return preferences.getFloat(key, 0.0F);
  }


  public static void putStringSet(Context context, String key, Set<String> set) {
    initPreference(context);
    preferences.putStringSet(key, set);
    preferences.flush();
  }

  /**
   * @param context  上下文
   * @param key 键
   * @return 获取set集合的默认值为:null
   */
  public static Set<String> getStringSet(Context context, String key) {
    initPreference(context);
    return preferences.getStringSet(key, null);
  }


  public static boolean deletePreferences(Context context) {
    initPreference(context);
    boolean isDelete= databaseHelper.deletePreferences(PREFERENCE_FILE_NAME);
    return isDelete;
  }


  public static void registerObserver(Context context,PreferencesObserver preferencesObserver){
    initPreference(context);
    mPreferencesObserver=preferencesObserver;
    preferences.registerObserver(mPreferencesObserver);
  }

  public static void unregisterObserver(){
    if(mPreferencesObserver!=null){
      // 向preferences实例注销观察者
      preferences.unregisterObserver(mPreferencesObserver);
    }
  }

}

2. MainAbilitySlice

public class MainAbilitySlice extends AbilitySlice implements ClickedListener {
  private TextField tfName;
  private TextField tfGener;
  private TextField tfAge;
  private TextField tfWeight;
  private Text tvResultQuery;
  private Text tvResultListener;
  private String name;
  private boolean isMan;
  private int age;
  private float weight;


  @Override
  public void onStart(Intent intent) {
    super.onStart(intent);
    super.setUIContent(ResourceTable.Layout_ability_main);
    tfName=(TextField)findComponentById(ResourceTable.Id_tf_name);
    tfGener=(TextField)findComponentById(ResourceTable.Id_tf_isMan);
    tfAge=(TextField)findComponentById(ResourceTable.Id_tf_age);
    tfWeight=(TextField)findComponentById(ResourceTable.Id_tf_weight);
    tvResultQuery=(Text) findComponentById(ResourceTable.Id_tvResultQuery);
    tvResultListener=(Text) findComponentById(ResourceTable.Id_tvResultListener);
    Button btSave=(Button)findComponentById(ResourceTable.Id_bt_save);
    Button btQuery=(Button)findComponentById(ResourceTable.Id_bt_query);
    Button btRegister=(Button)findComponentById(ResourceTable.Id_bt_regist);
    Button btUnRegister=(Button)findComponentById(ResourceTable.Id_bt_unregist);
    btSave.setClickedListener(this);
    btQuery.setClickedListener(this);
    btRegister.setClickedListener(this);
    btUnRegister.setClickedListener(this);
  }

  @Override
  public void onActive() {
    super.onActive();
  }

  @Override
  public void onForeground(Intent intent) {
    super.onForeground(intent);
  }

  @Override
  public void onClick(Component component) {
    switch (component.getId()){
      case ResourceTable.Id_bt_save:
        PreferenceUtils.putString(MyApplication.mContext,"name",tfName.getText());
        if(tfGener.getText().equals("男")){
          PreferenceUtils.putBoolean(MyApplication.mContext,"gender",true);
        }
        try {
          String age=tfAge.getText();
          String weight=tfWeight.getText();
          int ageInt=Integer.parseInt(age);
          float weightFloat=Float.parseFloat(weight);
          PreferenceUtils.putInt(MyApplication.mContext,"age",ageInt);
          PreferenceUtils.putFloat(MyApplication.mContext,"weight",weightFloat);
        }catch (Exception e){
          e.printStackTrace();
        }
        new ToastDialog(this).setDuration(2000).setText("保存成功").setAlignment(LayoutAlignment.CENTER).show();
        break;
      case ResourceTable.Id_bt_query:
         name=PreferenceUtils.getString(MyApplication.mContext,"name");
         isMan=PreferenceUtils.getBoolean(MyApplication.mContext,"gender");
         age=PreferenceUtils.getInt(MyApplication.mContext,"age");
         weight=PreferenceUtils.getFloat(MyApplication.mContext,"weight");
        if(isMan){
          tvResultQuery.setText("查询结果:"+name+"/男/"+age+"/"+weight);
        }else {
          tvResultQuery.setText("查询结果:"+name+"/女/"+age+"/"+weight);
        }
        new ToastDialog(this).setDuration(2000).setText("查询成功").setAlignment(LayoutAlignment.CENTER).show();
        break;
      case ResourceTable.Id_bt_regist:
        PreferenceUtils.registerObserver(this,new PreferencesObserver() {
          @Override
          public void onChange(Preferences preferences, String key) {
            switch (key){
              case "name":
                 name=PreferenceUtils.getString(MyApplication.mContext,"name");
                break;
              case "gender":
                 isMan=PreferenceUtils.getBoolean(MyApplication.mContext,"gender");
                break;
              case "age":
                 age=PreferenceUtils.getInt(MyApplication.mContext,"age");
                break;
              case "weight":
                 weight=PreferenceUtils.getFloat(MyApplication.mContext,"weight");
                break;
            }
            if(isMan){
              tvResultListener.setText("兼停结果:"+name+"/男/"+age+"/"+weight);
            }else {
              tvResultListener.setText("兼停结果:"+name+"/女/"+age+"/"+weight);
            }
          }

        });
        new ToastDialog(this).setDuration(2000).setText("注册成功").setAlignment(LayoutAlignment.CENTER).show();
        break;
      case ResourceTable.Id_bt_unregist:
        PreferenceUtils.unregisterObserver();
        new ToastDialog(this).setDuration(2000).setText("解除注册成功").setAlignment(LayoutAlignment.CENTER).show();
        break;
    }

  }



}

3. MyApplication

public class MyApplication extends AbilityPackage {
  public static Context mContext ;

  @Override
  public void onInitialize() {
    super.onInitialize();
    mContext=this;
  }
}

4.页面布局ability_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
  xmlns:ohos="http://schemas.huawei.com/res/ohos"
  ohos:height="match_parent"
  ohos:orientation="vertical"
  ohos:width="match_parent">

  <DirectionalLayout
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:orientation="vertical"
    ohos:left_padding="15vp"
    ohos:right_padding="15vp"
    ohos:top_padding="16vp">
    <Text
      ohos:height="match_content"
      ohos:width="match_content"
      ohos:text="姓名"
      ohos:text_size="18vp"/>
    <TextField
      ohos:id="$+id:tf_name"
      ohos:height="match_content"
      ohos:width="match_parent"
      ohos:text_input_type="pattern_text"
      ohos:hint="请输入姓名"
      ohos:text_size="18vp"
      ohos:hint_color="#cccccc"
      ohos:top_margin="8vp"/>
    <DirectionalLayout
      ohos:height="1vp"
      ohos:width="match_parent"
      ohos:top_margin="3vp"
      ohos:background_element="#cccccc"/>
  </DirectionalLayout>


  <DirectionalLayout
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:orientation="vertical"
    ohos:left_padding="15vp"
    ohos:right_padding="15vp"
    ohos:top_padding="16vp">
    <Text
      ohos:height="match_content"
      ohos:width="match_content"
      ohos:text="性别"
      ohos:text_size="18vp"/>
    <TextField
      ohos:id="$+id:tf_isMan"
      ohos:height="match_content"
      ohos:width="match_parent"
      ohos:text_input_type="pattern_text"
      ohos:hint="男/女"
      ohos:text_size="18vp"
      ohos:hint_color="#cccccc"
      ohos:top_margin="8vp"/>
    <DirectionalLayout
      ohos:height="1vp"
      ohos:width="match_parent"
      ohos:top_margin="3vp"
      ohos:background_element="#cccccc"/>
  </DirectionalLayout>


  <DirectionalLayout
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:orientation="vertical"
    ohos:left_padding="15vp"
    ohos:right_padding="15vp"
    ohos:top_padding="16vp">
    <Text
      ohos:height="match_content"
      ohos:width="match_content"
      ohos:text="年龄"
      ohos:text_size="18vp"/>
    <TextField
      ohos:id="$+id:tf_age"
      ohos:height="match_content"
      ohos:width="match_parent"
      ohos:text_input_type="pattern_number"
      ohos:hint="请输入年龄"
      ohos:text_size="18vp"
      ohos:hint_color="#cccccc"
      ohos:top_margin="8vp"/>
    <DirectionalLayout
      ohos:height="1vp"
      ohos:width="match_parent"
      ohos:top_margin="3vp"
      ohos:background_element="#cccccc"/>
  </DirectionalLayout>


  <DirectionalLayout
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:orientation="vertical"
    ohos:left_padding="15vp"
    ohos:right_padding="15vp"
    ohos:top_padding="16vp">
    <Text
      ohos:height="match_content"
      ohos:width="match_content"
      ohos:text="体重"
      ohos:text_size="18vp"/>
    <TextField
      ohos:id="$+id:tf_weight"
      ohos:height="match_content"
      ohos:width="match_parent"
      ohos:text_input_type="pattern_number"
      ohos:hint="请输入体重"
      ohos:text_size="18vp"
      ohos:hint_color="#cccccc"
      ohos:top_margin="8vp"/>
    <DirectionalLayout
      ohos:height="1vp"
      ohos:width="match_parent"
      ohos:top_margin="3vp"
      ohos:background_element="#cccccc"/>
  </DirectionalLayout>



  <DirectionalLayout
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:orientation="horizontal"
    ohos:top_margin="30vp"
    ohos:left_margin="15vp"
    ohos:right_margin="15vp">
    <Button
      ohos:id="$+id:bt_save"
      ohos:height="40vp"
      ohos:width="0"
      ohos:weight="1"
      ohos:text="保存"
      ohos:text_size="20vp"
      ohos:text_color="#ffffff"
      ohos:right_margin="30vp"
      ohos:background_element="$graphic:background_main_circle"
      ohos:layout_alignment="center"/>
    <Button
      ohos:id="$+id:bt_query"
      ohos:height="40vp"
      ohos:width="0"
      ohos:weight="1"
      ohos:text="查询"
      ohos:text_size="20vp"
      ohos:text_color="#ffffff"
      ohos:right_margin="30vp"
      ohos:background_element="$graphic:background_main_circle"
      ohos:layout_alignment="center"/>
  </DirectionalLayout>

  <DirectionalLayout
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:orientation="horizontal"
    ohos:top_margin="30vp"
    ohos:left_margin="15vp"
    ohos:right_margin="15vp">
    <Button
      ohos:id="$+id:bt_regist"
      ohos:height="40vp"
      ohos:width="0"
      ohos:weight="1"
      ohos:text="注册兼停"
      ohos:text_size="20vp"
      ohos:text_color="#ffffff"
      ohos:right_margin="30vp"
      ohos:background_element="$graphic:background_main_circle"
      ohos:layout_alignment="center"/>
    <Button
      ohos:id="$+id:bt_unregist"
      ohos:height="40vp"
      ohos:width="0"
      ohos:weight="1"
      ohos:text="解除注册"
      ohos:text_size="20vp"
      ohos:text_color="#ffffff"
      ohos:right_margin="30vp"
      ohos:background_element="$graphic:background_main_circle"
      ohos:layout_alignment="center"/>
  </DirectionalLayout>



  <Text
    ohos:id="$+id:tvResultQuery"
    ohos:height="match_content"
    ohos:width="match_content"
    ohos:text_size="18vp"
    ohos:text="查询结果:"
    ohos:background_element="#cccccc"
    ohos:layout_alignment="center"
    ohos:top_margin="30vp"
    ohos:padding="10vp"/>

  <Text
    ohos:id="$+id:tvResultListener"
    ohos:height="match_content"
    ohos:width="match_content"
    ohos:text_size="18vp"
    ohos:text="兼停结果:"
    ohos:background_element="#cccccc"
    ohos:layout_alignment="center"
    ohos:top_margin="30vp"
    ohos:padding="10vp"/>

</DirectionalLayout>

5.圆角背景图形background_main_circle.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:shape="rectangle">
    <corners
        ohos:radius="10"/>
    <solid
        ohos:color="#00aaf5"/>

</shape>

实现效果视频:https://harmonyos.51cto.com/show/7929

更多原创内容请关注:软通动力HarmonyOS学院

因敏感词问题故以兼停替换

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2021-8-25 09:50:41修改
17
收藏 16
回复
举报
8条回复
按时间正序
/
按时间倒序
软通田可辉
软通田可辉

张老师的文章写的很细致。

回复
2021-8-23 15:08:38
粉粉gg
粉粉gg

张老师文章排版好整齐哦

回复
2021-8-23 15:11:31
江湖人称鸿老师
江湖人称鸿老师

感谢张老师分享

回复
2021-8-24 09:07:02
可可学鸿蒙
可可学鸿蒙

感谢软通大佬分享

回复
2021-8-24 09:09:31
软通张二龙
软通张二龙 回复了 软通田可辉
张老师的文章写的很细致。

写的细致,大家才能更快学会

回复
2021-8-24 09:21:19
顾自由
顾自由

感谢张老师的分享,多多更新啊

回复
2021-8-24 09:31:07
软通动力HOS
软通动力HOS

感谢张老师分享

回复
2021-8-26 11:38:52
爱吃土豆丝的打工人
爱吃土豆丝的打工人

今天是数据库开发日嘛   热帖全部都是数据库哇

回复
2021-8-26 14:04:29
回复
    相关推荐