• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Sharing Data Using DataShareExtensionAbility
2
3
4## When to Use
5
6If complex services are involved in cross-application data access, you can use **DataShareExtensionAbility** to start the application of the data provider to implement data access.
7
8You need to implement flexible service logics via callbacks of the service provider.
9
10
11## Working Principles
12
13There are two roles in **DataShare**:
14
15- Data provider: implements operations, such as adding, deleting, modifying, and querying data, and opening a file, using [DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md).
16
17- Data consumer: accesses the data provided by the provider using [createDataShareHelper()](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper).
18
19**Figure 1** Data sharing mechanism
20
21![dataShare](figures/dataShare.jpg)
22
23- The **DataShareExtensionAbility** module, as the data provider, implements services related to data sharing between applications.
24
25- The **DataShareHelper** module, as the data consumer, provides APIs for accessing data, including adding, deleting, modifying, and querying data.
26
27- The data consumer communicates with the data provider via inter-process communication (IPC). The data provider can be implemented through a database or other data storage.
28
29- The **ResultSet** module is implemented through shared memory. Shared memory stores the result sets, and interfaces are provided to traverse result sets.
30
31
32## How to Develop
33
34
35### Data Provider Application Development (Only for System Applications)
36
37[DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md) provides the following APIs. You can override these APIs as required.
38
39- **onCreate**: called by the server to initialize service logic when the DataShare client connects to the DataShareExtensionAbility server.
40
41- **insert**: called to insert data upon the request of the client. Data insertion must be implemented in this callback on the server.
42
43- **update**: called to update data upon the request of the client. Data update must be implemented in this callback on the server.
44
45- **delete**: called to delete data upon the request of the client. Data deletion must be implemented in this callback on the server.
46
47- **query**: called to query data upon the request of the client. Data query must be implemented in this callback on the server.
48
49- **batchInsert**: called to batch insert data upon the request of the client. Batch data insertion must be implemented in this callback on the server.
50
51- **normalizeUri**: converts the URI provided by the client to the URI used by the server.
52
53- **denormalizeUri**: converts the URI used by the server to the initial URI passed by the client.
54
55Before implementing a **DataShare** service, you need to create a **DataShareExtensionAbility** object in the DevEco Studio project as follows:
56
571. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **DataShareExtAbility**.
58
592. Right-click the **DataShareAbility** directory, and choose **New > TypeScript File** to create a file named **DataShareExtAbility.ts**.
60
613. Import **@ohos.application.DataShareExtensionAbility** and other dependencies to the **DataShareExtAbility.ts** file, and
62override the service implementation as required. For example, if the data provider provides only the data insertion, deletion, and query services, you can override only these APIs.
63
64   ```js
65   import Extension from '@ohos.application.DataShareExtensionAbility';
66   import rdb from '@ohos.data.relationalStore';
67   import dataSharePredicates from '@ohos.data.dataSharePredicates';
68   ```
69
704. Implement the data provider services. For example, implement data storage of the data provider by using a database, reading and writing files, or accessing the network.
71
72   ```js
73   const DB_NAME = 'DB00.db';
74   const TBL_NAME = 'TBL00';
75   const DDL_TBL_CREATE = "CREATE TABLE IF NOT EXISTS "
76   + TBL_NAME
77   + ' (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, isStudent BOOLEAN, Binary BINARY)';
78
79   let rdbStore;
80   let result;
81
82   export default class DataShareExtAbility extends Extension {
83     private rdbStore_;
84
85     // Override onCreate().
86     onCreate(want, callback) {
87       result = this.context.cacheDir + '/datashare.txt';
88       // Create an RDB store.
89       rdb.getRdbStore(this.context, {
90         name: DB_NAME,
91         securityLevel: rdb.SecurityLevel.S1
92       }, function (err, data) {
93         rdbStore = data;
94         rdbStore.executeSql(DDL_TBL_CREATE, [], (err) => {
95           console.info(`DataShareExtAbility onCreate, executeSql done err:${err}`);
96         });
97         if (callback) {
98           callback();
99         }
100       });
101     }
102
103     // Override query().
104     query(uri, predicates, columns, callback) {
105       if (predicates === null || predicates === undefined) {
106         console.info('invalid predicates');
107       }
108       try {
109         rdbStore.query(TBL_NAME, predicates, columns, (err, resultSet) => {
110           if (resultSet !== undefined) {
111             console.info(`resultSet.rowCount:${resultSet.rowCount}`);
112           }
113           if (callback !== undefined) {
114             callback(err, resultSet);
115           }
116         });
117       } catch (err) {
118         console.error(`Failed to query. Code:${err.code},message:${err.message}`);
119       }
120     }
121     // Override other APIs as required.
122   };
123   ```
124
1255. Define **DataShareExtensionAbility** in **module.json5**.
126
127     **Table 1** Fields in module.json5
128
129   | Field| Description| Mandatory|
130   | -------- | -------- | -------- |
131   | name | Ability name, corresponding to the **ExtensionAbility** class name derived from **Ability**.| Yes|
132   | type | Ability type. The value is **dataShare**, indicating the development is based on the **datashare** template.| Yes|
133   | uri | URI used for communication. It is the unique identifier for the data consumer to connect to the provider.| Yes|
134   | exported | Whether it is visible to other applications. Data sharing is allowed only when the value is **true**.| Yes|
135   | readPermission | Permission required for accessing data. If this parameter is not set, the read permission is not verified by default.| No|
136   | writePermission | Permission required for modifying data. If this parameter is not set, write permission verification is not performed by default.| No|
137
138   **module.json5 example**
139
140
141   ```json
142   "extensionAbilities": [
143     {
144       "srcEntrance": "./ets/DataShareExtAbility/DataShareExtAbility.ts",
145       "name": "DataShareExtAbility",
146       "icon": "$media:icon",
147       "description": "$string:description_datashareextability",
148       "type": "dataShare",
149       "uri": "datashare://com.samples.datasharetest.DataShare",
150       "exported": true
151     }
152   ]
153   ```
154
155
156### Data Consumer Application Development
157
1581. Import the dependencies.
159
160   ```js
161   import UIAbility from '@ohos.app.ability.UIAbility';
162   import dataShare from '@ohos.data.dataShare';
163   import dataSharePredicates from '@ohos.data.dataSharePredicates';
164   ```
165
1662. Define the URI string for communicating with the data provider.
167
168   ```js
169   // Different from the URI defined in the module.json5 file, the URI passed in the parameter has an extra slash (/), because there is a DeviceID parameter between the second and the third slash (/).
170   let dseUri = ('datashare:///com.samples.datasharetest.DataShare');
171   ```
172
1733. Create a **DataShareHelper** instance.
174
175   ```js
176   let dsHelper;
177   let abilityContext;
178
179   export default class EntryAbility extends UIAbility {
180     onWindowStageCreate(windowStage) {
181       abilityContext = this.context;
182       dataShare.createDataShareHelper(abilityContext, dseUri, (err, data) => {
183         dsHelper = data;
184       });
185     }
186   }
187   ```
188
1894. Use the APIs provided by **DataShareHelper** to access the services provided by the provider, for example, adding, deleting, modifying, and querying data.
190
191   ```js
192   // Construct a piece of data.
193   let valuesBucket = { 'name': 'ZhangSan', 'age': 21, 'isStudent': false, 'Binary': new Uint8Array([1, 2, 3]) };
194   let updateBucket = { 'name': 'LiSi', 'age': 18, 'isStudent': true, 'Binary': new Uint8Array([1, 2, 3]) };
195   let predicates = new dataSharePredicates.DataSharePredicates();
196   let valArray = ['*'];
197   // Insert a piece of data.
198   dsHelper.insert(dseUri, valuesBucket, (err, data) => {
199     console.info(`dsHelper insert result:${data}`);
200   });
201   // Update data.
202   dsHelper.update(dseUri, predicates, updateBucket, (err, data) => {
203     console.info(`dsHelper update result:${data}`);
204   });
205   // Query data.
206   dsHelper.query(dseUri, predicates, valArray, (err, data) => {
207     console.info(`dsHelper query result:${data}`);
208   });
209   // Delete data.
210   dsHelper.delete(dseUri, predicates, (err, data) => {
211     console.info(`dsHelper delete result:${data}`);
212   });
213   ```
214