赞
踩
使用Data模板的Ability(以下简称“Data”)有助于应用管理其自身和其他应用存储数据的访问,并提供与其他应用共享数据的方法。Data既可用于同设备不同应用的数据共享,也支持跨设备不同应用的数据共享。
数据的存放形式多样,可以是数据库,也可以是磁盘上的文件。Data对外提供对数据的增、删、改、查,以及打开文件等接口,这些接口的具体实现由开发者提供。
Data的提供方和使用方都通过URI(Uniform Resource Identifier)来标识一个具体的数据,例如数据库中的某个表或磁盘上的某个文件。HarmonyOS的URI仍基于URI通用标准,格式如下:
URI示例:
开发者可以通过DataAbilityHelper类来访问当前应用或其他应用提供的共享数据。DataAbilityHelper作为客户端,与提供方的Data进行通信。Data接收到请求后,执行相应的处理,并返回结果。DataAbilityHelper提供了一系列与Data Ability对应的方法。
下面介绍DataAbilityHelper具体的使用步骤。
如果待访问的Data声明了访问需要权限,则访问此Data需要在配置文件中声明需要此权限。声明请参考权限申请字段说明。
- "reqPermissions": [
- {
- "name": "com.example.myapplication5.DataAbility.DATA"
- }
- ]
DataAbilityHelper为开发者提供了creator()方法来创建DataAbilityHelper实例。该方法为静态方法,有多个重载。最常见的方法是通过传入一个context对象来创建DataAbilityHelper对象。
获取helper对象示例:
DataAbilityHelper为开发者提供了一系列的接口来访问不同类型的数据(文件、数据库等)。
DataAbilityHelper为开发者提供了FileDescriptor openFile(Uri uri, String mode)方法来操作文件。此方法需要传入两个参数,其中uri用来确定目标资源路径,mode用来指定打开文件的方式,可选方式包含“r”(读), “w”(写), “rw”(读写),“wt”(覆盖写),“wa”(追加写),“rwt”(覆盖写且可读)。
该方法返回一个目标文件的FD(文件描述符),把文件描述符封装成流,开发者就可以对文件流进行自定义处理。
访问文件示例:
方法 | 描述 |
---|---|
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<DataAbilityOperation> operations) | 批量操作数据库 |
- DataAbilityHelper helper = DataAbilityHelper.creator(this);
-
- // 构造查询条件
- DataAbilityPredicates predicates = new DataAbilityPredicates();
- predicates.between("userId", 101, 103);
-
- // 进行查询
- ResultSet resultSet = helper.query(uri,columns,predicates);
-
- // 处理结果
- resultSet.goToFirstRow();
- do{
- // 在此处理ResultSet中的记录;
- }while(resultSet.goToNextRow());
- DataAbilityHelper helper = DataAbilityHelper.creator(this);
-
- // 构造插入数据
- ValuesBucket valuesBucket = new ValuesBucket();
- valuesBucket.putString("name", "Tom");
- valuesBucket.putInteger("age", 12);
- helper.insert(uri, valuesBucket);
- DataAbilityHelper helper = DataAbilityHelper.creator(this);
-
- // 构造插入数据
- ValuesBucket[] values = new ValuesBucket[2];
- value[0] = new ValuesBucket();
- value[0].putString("name", "Tom");
- value[0].putInteger("age", 12);
- value[1] = new ValuesBucket();
- value[1].putString("name", "Tom1");
- value[1].putInteger("age", 16);
- helper.batchInsert(uri, values);
删除方法,其中删除条件可以通过DataAbilityPredicates来构建。删除用户表中id在101-103之间的用户,代码示例如下:
- DataAbilityHelper helper = DataAbilityHelper.creator(this);
-
- // 构造删除条件
- DataAbilityPredicates predicates = new DataAbilityPredicates();
- predicates.between("userId", 101,103);
- helper.delete(uri,predicates);
更新方法,更新数据由ValuesBucket传入,更新条件由DataAbilityPredicates来构建。更新id为102的用户,代码示例如下:
- DataAbilityHelper helper = DataAbilityHelper.creator(this);
-
- // 构造更新条件
- DataAbilityPredicates predicates = new DataAbilityPredicates();
- predicates.equalTo("userId",102);
-
- // 构造更新数据
- ValuesBucket valuesBucket = new ValuesBucket();
- valuesBucket.putString("name", "Tom");
- valuesBucket.putInteger("age", 12);
- helper.update(uri, valuesBucket, predicates);
此方法用来执行批量操作。DataAbilityOperation中提供了设置操作类型、数据和操作条件的方法,开发者可自行设置自己要执行的数据库操作。插入多条数据的代码示例如下:
使用Data模板的Ability形式仍然是Ability,因此,开发者需要为应用添加一个或多个Ability的子类,来提供程序与其他应用之间的接口。Data为结构化数据和文件提供了不同API接口供用户使用,因此,开发者需要首先确定好使用何种类型的数据。本章节主要讲述了创建Data的基本步骤和需要使用的接口。
UserDataAbility接收其他应用发送的请求,提供外部程序访问的入口,从而实现应用间的数据访问。Data提供了文件存储和数据库存储两组接口供用户使用。
文件存储
开发者需要在Data中重写FileDescriptor openFile(Uri uri, String mode)方法来操作文件:uri为客户端传入的请求目标路径;mode为开发者对文件的操作选项,可选方式包含“r”(读), “w”(写), “rw”(读写)等。
MessageParcel类提供了一个静态方法,用于获取MessageParcel实例。通过dupFileDescriptor()函数复制待操作文件流的文件描述符,并将其返回,供远端应用使用。
示例:根据传入的uri打开对应的文件
- // 创建messageParcel
- MessageParcel messageParcel = MessageParcel.obtain();
- File file = new File(uri.getDecodedPathList().get(1));
- if (mode == null || !"rw".equals(mode)) {
- file.setReadOnly();
- }
- FileInputStream fileIs = new FileInputStream(file);
- FileDescriptor fd = fileIs.getFD();
-
- // 绑定文件描述符
- return messageParcel.dupFileDescriptor(fd);
数据库存储
系统会在应用启动时调用onStart()方法创建Data实例。在此方法中,开发者应该创建数据库连接,并获取连接对象,以便后续和数据库进行操作。为了避免影响应用启动速度,开发者应当尽可能将非必要的耗时任务推迟到使用时执行,而不是在此方法中执行所有初始化。
示例:初始化的时候连接数据库
- private static final String DATABASE_NAME ="UserDataAbility.db";
- private static final String DATABASE_NAME_ALIAS = "UserDataAbility";
- private OrmContext ormContext = null;
-
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- DatabaseHelper manager = new DatabaseHelper(this);
- ormContext = manager.getOrmContext(DATABASE_NAME_ALIAS, DATABASE_NAME, BookStore.class);
- }
方法 | 描述 |
---|---|
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<DataAbilityOperation> operations) | 批量操作数据库 |
该方法接收三个参数,分别是查询的目标路径,查询的列名,以及查询条件,查询条件由类DataAbilityPredicates构建。根据传入的列名和查询条件查询用户表的代码示例如下:
- public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
- if (ormContext == null) {
- HiLog.error(this.getClass().getSimpleName(), "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(this.getClass(), "resultSet is null");
- }
-
- // 返回结果
- return resultSet;
- }

该方法接收两个参数,分别是插入的目标路径和插入的数据值。其中,插入的数据由ValuesBucket封装,服务端可以从该参数中解析出对应的属性,然后插入到数据库中。此方法返回一个int类型的值用于标识结果。接收到传过来的用户信息并把它保存到数据库中的代码示例如下:
- public int insert(Uri uri, ValuesBucket value) {
- // 参数校验
- if (ormContext == null) {
- HiLog.error(this.getClass().getSimpleName(), "failed to insert, ormContext is null");
- return -1;
- }
- String path = uri.getPath();
-
- if (buildPathMatcher().getPathId(path) != PathId) {
- HiLog.info(this.getClass(), "UserDataAbility insert path is not matched");
- 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 isSuccessed = true;
- try {
- isSuccessed = ormContext.insert(user);
- } catch (DataAbilityRemoteException e) {
- HiLog.error(TAG, "insert fail: " + e.getMessage());
- throw new RuntimeException(e);
- }
- if (!isSuccessed) {
- HiLog.error(this.getClass().getSimpleName(), "failed to insert");
- return -1;
- }
- isSuccessed = ormContext.flush();
- if (!isSuccessed) {
- HiLog.error(this.getClass().getSimpleName(), "failed to insert flush");
- return -1;
- }
- DataAbilityHelper.creator(this, uri).notifyChange(uri);
- int id = Math.toIntExact(user.getRowId());
- return id;
- }

该方法为批量插入方法,接收一个ValuesBucket数组用于单次插入一组对象。它的作用是提高插入多条重复数据的效率。该方法系统已实现,开发者可以直接调用。
该方法用来执行删除操作。删除条件由类DataAbilityPredicates构建,服务端在接收到该参数之后可以从中解析出要删除的数据,然后到数据库中执行。根据传入的条件删除用户表数据的代码示例如下:
- public int delete(Uri uri, DataAbilityPredicates predicates) {
- if (ormContext == null) {
- HiLog.error(this.getClass().getSimpleName(), "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;
- }
此方法用来执行更新操作。用户可以在ValuesBucket参数中指定要更新的数据,在DataAbilityPredicates中构建更新的条件等。更新用户表的数据的代码示例如下:
- public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
- if (ormContext == null) {
- HiLog.error(this.getClass().getSimpleName(), "failed to update, ormContext is null");
- return -1;
- }
-
- OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
- int index = ormContext.update(ormPredicates, value);
- HiLog.info(this.getClass(), "UserDataAbility update value:" + index);
- DataAbilityHelper.creator(this, uri).notifyChange(uri);
- return index;
- }
此方法用来批量执行操作。DataAbilityOperation中提供了设置操作类型、数据和操作条件的方法,用户可自行设置自己要执行的数据库操作。该方法系统已实现,开发者可以直接调用。
和Service类似,开发者必须在配置配置文件中注册Data。并且配置以下属性:
- {
- "name": ".UserDataAbility",
- "type": "data",
- "visible": true,
- "uri": "dataability://com.example.myapplication5.DataAbilityTest",
- "permissions": [
- "com.example.myapplication5.DataAbility.DATA"
- ]
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。