一、DataAbility基本概念

在HarmonyOS 5中,DataAbility是一种特殊类型的Ability,主要用于提供统一的数据访问接口,实现应用间的数据共享与交互。DataAbility基于标准的数据模型,可以封装各种数据源(如数据库、文件、网络等),对外提供CRUD(创建、读取、更新、删除)操作接口。

DataAbility的核心特点包括:

  1. 数据抽象:将底层数据存储细节封装,提供统一访问接口
  2. 跨应用共享:通过URI机制实现安全可控的数据共享
  3. 标准化操作:支持标准的数据操作接口,简化开发流程

二、DataAbility配置与实现

1. 配置module.json5

首先需要在module.json5中声明DataAbility:

{
  "module": {
    "abilities": [
      {
        "name": "DataAbility",
        "type": "data",
        "uri": "dataability://com.example.myapplication.DataAbility",
        "visible": true,
        "permissions": [
          "com.example.myapplication.DataAbility.DATA"
        ]
      }
    ]
  }
}

2. 实现DataAbility子类

创建一个继承自DataAbilityHelper的类,实现核心数据操作逻辑:

import dataAbility from '@ohos.data.dataAbility';
import relationalStore from '@ohos.data.relationalStore';

const DB_NAME = 'myDatabase.db';
const TABLE_NAME = 'user';
const DB_VERSION = 1;

export default class MyDataAbility extends dataAbility.DataAbilityHelper {
  private rdbStore: relationalStore.RdbStore | null = null;

  // 初始化数据库
  async onInitialized(): Promise<void> {
    try {
      const config: relationalStore.StoreConfig = {
        name: DB_NAME,
        securityLevel: relationalStore.SecurityLevel.S1
      };
      this.rdbStore = await relationalStore.getRdbStore(this.context, config);
      
      // 创建表
      const sql = `CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        age INTEGER,
        email TEXT
      )`;
      await this.rdbStore.executeSql(sql);
      console.info('Database initialized successfully');
    } catch (error) {
      console.error(`Failed to initialize database: ${error}`);
    }
  }

  // 插入数据
  async insert(uri: string, valueBucket: dataAbility.ValuesBucket): Promise<number> {
    if (!this.rdbStore) {
      throw new Error('Database not initialized');
    }
    
    try {
      const result = await this.rdbStore.insert(TABLE_NAME, valueBucket);
      return result;
    } catch (error) {
      console.error(`Insert failed: ${error}`);
      throw error;
    }
  }

  // 查询数据
  async query(
    uri: string,
    columns: Array<string>,
    predicates: dataAbility.DataAbilityPredicates
  ): Promise<dataAbility.ResultSet> {
    if (!this.rdbStore) {
      throw new Error('Database not initialized');
    }
    
    try {
      const result = await this.rdbStore.query(
        predicates,
        columns
      );
      return result;
    } catch (error) {
      console.error(`Query failed: ${error}`);
      throw error;
    }
  }

  // 更新数据
  async update(
    uri: string,
    valueBucket: dataAbility.ValuesBucket,
    predicates: dataAbility.DataAbilityPredicates
  ): Promise<number> {
    if (!this.rdbStore) {
      throw new Error('Database not initialized');
    }
    
    try {
      const changedRows = await this.rdbStore.update(
        valueBucket,
        predicates
      );
      return changedRows;
    } catch (error) {
      console.error(`Update failed: ${error}`);
      throw error;
    }
  }

  // 删除数据
  async delete(
    uri: string,
    predicates: dataAbility.DataAbilityPredicates
  ): Promise<number> {
    if (!this.rdbStore) {
      throw new Error('Database not initialized');
    }
    
    try {
      const deletedRows = await this.rdbStore.delete(
        predicates
      );
      return deletedRows;
    } catch (error) {
      console.error(`Delete failed: ${error}`);
      throw error;
    }
  }
}

三、DataAbility客户端调用示例

下面是一个使用DataAbility的完整ArkUI页面示例:

@Entry
@Component
struct DataAbilityDemo {
  @State users: Array<any> = [];
  @State name: string = '';
  @State age: string = '';
  @State email: string = '';

  private dataAbilityHelper = new dataAbility.DataAbilityHelper(
    'dataability://com.example.myapplication.DataAbility'
  );

  // 加载所有用户数据
  async loadUsers() {
    try {
      const predicates = new dataAbility.DataAbilityPredicates();
      const columns = ['id', 'name', 'age', 'email'];
      const resultSet = await this.dataAbilityHelper.query(
        '', 
        columns, 
        predicates
      );
      
      this.users = [];
      while (resultSet.goToNextRow()) {
        this.users.push({
          id: resultSet.getLong(resultSet.getColumnIndex('id')),
          name: resultSet.getString(resultSet.getColumnIndex('name')),
          age: resultSet.getLong(resultSet.getColumnIndex('age')),
          email: resultSet.getString(resultSet.getColumnIndex('email'))
        });
      }
      resultSet.close();
    } catch (error) {
      console.error(`Failed to query users: ${error}`);
    }
  }

  // 添加新用户
  async addUser() {
    if (!this.name || !this.age) return;
    
    try {
      const valueBucket = {
        name: this.name,
        age: parseInt(this.age),
        email: this.email || null
      };
      await this.dataAbilityHelper.insert('', valueBucket);
      await this.loadUsers(); // 刷新列表
      
      // 清空输入
      this.name = '';
      this.age = '';
      this.email = '';
    } catch (error) {
      console.error(`Failed to add user: ${error}`);
    }
  }

  build() {
    Column() {
      // 输入表单
      Row() {
        TextInput({ placeholder: 'Name' })
          .width('30%')
          .onChange((value: string) => { this.name = value })
        TextInput({ placeholder: 'Age' })
          .width('20%')
          .onChange((value: string) => { this.age = value })
        TextInput({ placeholder: 'Email' })
          .width('40%')
          .onChange((value: string) => { this.email = value })
        Button('Add')
          .onClick(() => this.addUser())
      }.padding(10)

      // 用户列表
      List({ space: 10 }) {
        ForEach(this.users, (user: any) => {
          ListItem() {
            Row() {
              Text(user.name)
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .layoutWeight(1)
              Text(`Age: ${user.age}`)
                .fontSize(16)
                .layoutWeight(1)
              Text(user.email || 'No email')
                .fontSize(16)
                .layoutWeight(2)
            }
          }
          .borderRadius(10)
          .backgroundColor('#f5f5f5')
          .padding(10)
        })
      }
      .layoutWeight(1)
      .onAppear(() => this.loadUsers()) // 页面显示时加载数据
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

四、高级特性与最佳实践

  1. 数据权限控制

    • 通过URI权限机制控制数据访问
    • 实现自定义权限验证逻辑
  2. 数据变更通知

    • 使用DataObserver注册数据变更监听
    • 实现数据实时更新功能
  3. 性能优化

    • 批量操作减少数据库IO
    • 使用事务保证数据一致性
  4. 错误处理

    • 实现健壮的错误处理机制
    • 提供有意义的错误信息

五、总结

HarmonyOS 5的DataAbility组件为开发者提供了强大的数据共享与管理能力。通过本文的讲解和示例代码,开发者可以快速掌握DataAbility的配置与使用方法,实现安全高效的数据访问与共享。在实际开发中,建议结合具体业务需求,灵活运用DataAbility的各种特性,构建更加强大和灵活的HarmonyOS应用。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐