创建Data

使用Data模板的Ability形式仍然是Ability,因此,开发者需要为应用添加一个或多个Ability的子类,来提供程序与其他应用之间的接口。Data为结构化数据和文件提供了不同API接口供用户使用,因此,开发者需要首先确定好使用何种类型的数据。本章节主要讲述了创建Data的基本步骤和需要使用的接口。

Data提供方可以自定义数据的增、删、改、查,以及文件打开等功能,并对外提供这些接口。

确定数据存储方式

确定数据的存储方式,Data支持以下两种数据形式:

  • 文件数据:如文本、图片、音乐等。
  • 结构化数据:如数据库等。

实现UserDataAbility

UserDataAbility用于接收其他应用发送的请求,提供外部程序访问的入口,从而实现应用间的数据访问。

实现UserDataAbility,需要在“Project”窗口当前工程的主目录(“entry > src > main > java > com.xxx.xxx”)选择“File > New > Ability > Empty Data Ability”,设置“Data Name”后完成UserDataAbility的创建。

Data提供了文件存储和数据库存储两组接口供用户使用。

文件存储

开发者需要在Data中重写FileDescriptor openFile(Uri uri, String mode)方法来操作文件:uri为客户端传入的请求目标路径;mode为开发者对文件的操作选项,可选方式包含“r”(读), “w”(写), “rw”(读写)等。

ohos.rpc.MessageParcel类提供了一个静态方法,用于获取MessageParcel实例。开发者可通过获取到的MessageParcel实例,使用dupFileDescriptor()函数复制待操作文件流的文件描述符,并将其返回,供远端应用访问文件。

示例:根据传入的uri打开对应的文件

private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0xD00201, "Data_Log");
@Overridepublic FileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {    // 创建messageParcel    MessageParcel messageParcel = MessageParcel.obtain();    File file = new File(uri.getDecodedPathList().get(0)); //get(0)是获取URI完整字段中查询参数字段。    if (mode == null || !"rw".equals(mode)) {        file.setReadOnly();    }    FileInputStream fileIs = new FileInputStream(file);    FileDescriptor fd = null;    try {        fd = fileIs.getFD();    } catch (IOException e) {        HiLog.info(LABEL_LOG, "failed to getFD");    }
    // 绑定文件描述符    return messageParcel.dupFileDescriptor(fd);}

数据库存储

  1. 初始化数据库连接。

    系统会在应用启动时调用onStart()方法创建Data实例。在此方法中,开发者应该创建数据库连接,并获取连接对象,以便后续和数据库进行操作。为了避免影响应用启动速度,开发者应当尽可能将非必要的耗时任务推迟到使用时执行,而不是在此方法中执行所有初始化。

    示例:初始化的时候连接数据库

    private static final String DATABASE_NAME = "UserDataAbility.db";private static final String DATABASE_NAME_ALIAS = "UserDataAbility";private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0xD00201, "Data_Log");private OrmContext ormContext = null;
    @Overridepublic void onStart(Intent intent) {    super.onStart(intent);    DatabaseHelper manager = new DatabaseHelper(this);    ormContext = manager.getOrmContext(DATABASE_NAME_ALIAS, DATABASE_NAME, BookStore.class);}
    
  2. 编写数据库操作方法。

    Ability定义了6个方法供用户处理对数据库表数据的增删改查。这6个方法在Ability中已默认实现,开发者可按需重写。

    | 方法 | 描述 | | ------------------------------------------------------------ | ---------------------- | | ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) | 查询数据库 | | int insert(Uri uri, ValuesBucket value) | 向数据库中插入单条数据 | | int batchInsert(Uri uri, ValuesBucket[] values) | 向数据库中插入多条数据 | | int delete(Uri uri, DataAbilityPredicates predicates) | 删除一条或多条数据 | | int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) | 更新数据库 | | DataAbilityResult[] executeBatch(ArrayList operations) | 批量操作数据库 |

    这些方法的使用说明如下:

    • query()

      该方法接收三个参数,分别是查询的目标路径,查询的列名,以及查询条件,查询条件由类DataAbilityPredicates构建。根据传入的列名和查询条件查询用户表的代码示例如下:

      public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {    if (ormContext == null) {        HiLog.error(LABEL_LOG, "failed to query, ormContext is null");        return null;    }
          // 查询数据库    OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);    ResultSet resultSet = ormContext.query(ormPredicates, columns);    if (resultSet == null) {        HiLog.info(LABEL_LOG, "resultSet is null");    }
          // 返回结果    return resultSet;}
      
    • insert()

      该方法接收两个参数,分别是插入的目标路径和插入的数据值。其中,插入的数据由ValuesBucket封装,服务端可以从该参数中解析出对应的属性,然后插入到数据库中。此方法返回一个int类型的值用于标识结果。接收到传过来的用户信息并把它保存到数据库中的代码示例如下:

      public int insert(Uri uri, ValuesBucket value) {    // 参数校验    if (ormContext == null) {        HiLog.error(LABEL_LOG, "failed to insert, ormContext is null");        return -1;    }
          // 构造插入数据    User user = new User();    user.setUserId(value.getInteger("userId"));    user.setFirstName(value.getString("firstName"));    user.setLastName(value.getString("lastName"));    user.setAge(value.getInteger("age"));    user.setBalance(value.getDouble("balance"));
          // 插入数据库    boolean isSuccessful = ormContext.insert(user);    if (!isSuccessful) {        HiLog.error(LABEL_LOG, "failed to insert");        return -1;    }    isSuccessful = ormContext.flush();    if (!isSuccessful) {        HiLog.error(LABEL_LOG, "failed to insert flush");        return -1;    }    DataAbilityHelper.creator(this, uri).notifyChange(uri);    int id = Math.toIntExact(user.getRowId());    return id;}
      
    • batchInsert()

      该方法为批量插入方法,接收一个ValuesBucket数组用于单次插入一组对象。它的作用是提高插入多条重复数据的效率。该方法系统已实现,开发者可以直接调用。

    • delete()

      该方法用来执行删除操作。删除条件由类DataAbilityPredicates构建,服务端在接收到该参数之后可以从中解析出要删除的数据,然后到数据库中执行。根据传入的条件删除用户表数据的代码示例如下:

      public int delete(Uri uri, DataAbilityPredicates predicates) {    if (ormContext == null) {        HiLog.error(LABEL_LOG, "failed to delete, ormContext is null");        return -1;    }
          OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);    int value = ormContext.delete(ormPredicates);    DataAbilityHelper.creator(this, uri).notifyChange(uri);    return value;}
      
    • update()

      此方法用来执行更新操作。用户可以在ValuesBucket参数中指定要更新的数据,在DataAbilityPredicates中构建更新的条件等。更新用户表的数据的代码示例如下:

      public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {    if (ormContext == null) {       HiLog.error(LABEL_LOG, "failed to update, ormContext is null");       return -1;   }
         OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);   int index = ormContext.update(ormPredicates, value);   HiLog.info(LABEL_LOG, "UserDataAbility update value:" + index);   DataAbilityHelper.creator(this, uri).notifyChange(uri);   return index;}
      
    • executeBatch()

      此方法用来批量执行操作。DataAbilityOperation中提供了设置操作类型、数据和操作条件的方法,用户可自行设置自己要执行的数据库操作。该方法系统已实现,开发者可以直接调用。

说明

上述代码示例中,初始化了数据库类BookStore.class,并通过实体类User.class对该数据库的表User进行增删改查操作。

关于对象关系映射数据库的具体逻辑,以及示例中BookStore.class与User.class的逻辑关系,可参考“对象关系映射数据库开发指导”。

注册UserDataAbility

和Service类似,开发者必须在配置文件中注册Data。

配置文件中该字段在创建Data Ability时会自动创建,name与创建的Data Ability一致。

需要关注以下属性:

  • type: 类型设置为data

  • uri: 对外提供的访问路径,全局唯一

  • permissions: 访问该data ability时需要申请的访问权限

    说明

    如果权限非系统权限,需要在配置文件中进行自定义。请参考权限开发指导中关于“自定义权限”的相关说明。

{    "name": ".UserDataAbility",     "type": "data",     "visible": true,     "uri": "dataability://com.example.myapplication5.DataAbilityTest",     "permissions": [        "com.example.myapplication5.DataAbility.DATA"     ]}

results matching ""

    No results matching ""