新聞中心
HarmonyOS基礎(chǔ)技術(shù)賦能之分布式數(shù)據(jù)服務(wù)功能
作者:軟通張二龍 2021-08-27 09:57:18
開發(fā)
前端
分布式
OpenHarmony 分布式數(shù)據(jù)服務(wù)(Distributed Data Service,DDS) 為應(yīng)用程序提供不同設(shè)備間數(shù)據(jù)庫數(shù)據(jù)分布式的能力。通過調(diào)用分布式數(shù)據(jù)接口,應(yīng)用程序?qū)?shù)據(jù)保存到分布式數(shù)據(jù)庫中。

想了解更多內(nèi)容,請訪問:
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
引言
分布式數(shù)據(jù)服務(wù)(Distributed Data Service,DDS) 為應(yīng)用程序提供不同設(shè)備間數(shù)據(jù)庫數(shù)據(jù)分布式的能力。通過調(diào)用分布式數(shù)據(jù)接口,應(yīng)用程序?qū)?shù)據(jù)保存到分布式數(shù)據(jù)庫中。通過結(jié)合帳號、應(yīng)用和數(shù)據(jù)庫三元組,分布式數(shù)據(jù)服務(wù)對屬于不同應(yīng)用的數(shù)據(jù)進(jìn)行隔離,保證不同應(yīng)用之間的數(shù)據(jù)不能通過分布式數(shù)據(jù)服務(wù)互相訪問。在通過可信認(rèn)證的設(shè)備間,分布式數(shù)據(jù)服務(wù)支持應(yīng)用數(shù)據(jù)相互同步,為用戶提供在多種終端設(shè)備上最終一致的數(shù)據(jù)訪問體驗。
功能介紹
此次通過HarmonyOS的分布式數(shù)據(jù)服務(wù)能力,一方面可以實現(xiàn)自身應(yīng)用界面的數(shù)據(jù)實時更新;另一方面也可以實現(xiàn)不同設(shè)備之間的數(shù)據(jù)實時更新。前提是在不同設(shè)備之間,要實現(xiàn)分布式數(shù)據(jù)服務(wù)的同步能力,需要同一個華為賬號登錄、并一個應(yīng)用包名、同一個網(wǎng)絡(luò)之間進(jìn)行,也可以兩個設(shè)備同時開啟藍(lán)牙。
開發(fā)指南
1. 在config.json中添加permisssion權(quán)限。
- // 添加在abilities同一目錄層級
- "reqPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ]
2. 在MainAbility中添加權(quán)限
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setMainRoute(MainAbilitySlice.class.getName());
- //實現(xiàn)Ability的代碼中顯式聲明需要使用多設(shè)備協(xié)同訪問的權(quán)限
- requestPermissionsFromUser(new String[]{
- "ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
- }
3. 根據(jù)配置構(gòu)造分布式數(shù)據(jù)庫管理類實例KvManager以及創(chuàng)建分布式數(shù)據(jù)庫對象SingleKvStore。
- //實現(xiàn)數(shù)據(jù)庫的初始化
- // 初入的參數(shù)context: Context context = getApplicationContext()獲得;storeId為分布式數(shù)據(jù)庫id,String類型,可自行定義,例如“testApp”。
- public static SingleKvStore initOrGetDB(Context context, String storeId) {
- KvManagerConfig kvManagerConfig = new KvManagerConfig(context);
- kvManager = KvManagerFactory.getInstance().createKvManager(kvManagerConfig);
- Options options = new Options();
- options.setCreateIfMissing(true)
- .setEncrypt(false)
- .setKvStoreType(KvStoreType.SINGLE_VERSION) //數(shù)據(jù)庫類型:單版本分布式數(shù)據(jù)庫
- .setAutoSync(true);//設(shè)置數(shù)據(jù)為自動同步
- singleKvStore = kvManager.getKvStore(options, storeId);
- return singleKvStore;
- }
4. 將數(shù)據(jù)寫入單版本分布式數(shù)據(jù)庫。
- //以key-value形式存儲到分布式數(shù)據(jù)庫
- try {
- long id = System.currentTimeMillis();
- singleKvStore.putString("key",
- "{\"id\":" + id +
- ",\"temp\":" + temperature +
- ",\"humidity\":" + humidity +
- ",\"NH4\":" + 0.0 +
- ",\"H2S\":" + 0.0 +
- ",\"other\":" + gas + "}");
- } catch (KvStoreException e) {
- e.printStackTrace();
- }
5.訂閱分布式數(shù)據(jù)變化??蛻舳诵枰獙崿F(xiàn)KvStoreObserver接口,監(jiān)聽數(shù)據(jù)變化。
- try {
- //訂閱類型SubscribeType.SUBSCRIBE_TYPE_ALL意思可以同步到本機(jī)和其他外圍設(shè)備
- innerKvStoreObserver = new InnerKvStoreObserver();
- singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, innerKvStoreObserver);
- } catch (KvStoreException e) {
- e.printStackTrace();
- }
- public class InnerKvStoreObserver implements KvStoreObserver {
- @Override
- public void onChange(ChangeNotification changeNotification) {
- //刷新頁面上的數(shù)據(jù),同樣有一個坑,onChange方法實質(zhì)上,在一個子線程里執(zhí)行
- MainAbilitySlice.taskDispatcher.asyncDispatch(() -> {
- //在這里執(zhí)行頁面ui組件的顯示刷新
- flushUIData();
- });
- }
- }
6.獲取分布式數(shù)據(jù)庫數(shù)據(jù)
- private void flushUIData() {
- //查詢分布式數(shù)據(jù)的數(shù)據(jù),獲取數(shù)據(jù)可以通過get(String key)/ getEntries(String key)方法獲取數(shù)據(jù)
- List
entries = singleKvStore.getEntries(“key”); - if (entries.size() > 0) {
- ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString());
- int temp = zsonObject.getIntValue("temp");
- int humidity = zsonObject.getIntValue("humidity");
- int other = zsonObject.getIntValue("other");
- tvTemp.setText(temp+"℃");
- tvHumi.setText(humidity+"% RH");
- tvGas.setText(other+"% LEL");
- }
7. 解除訂閱。一般在頁面銷毀時調(diào)用,也就是MainAbilitySlice的onStop()中調(diào)用
- if (singleKvStore != null) {
- singleKvStore.unSubscribe(innerKvStoreObserver);
- }
8. 同步數(shù)據(jù)到其他設(shè)備。獲取已連接的設(shè)備列表,選擇同步方式進(jìn)行數(shù)據(jù)同步
- List
deviceInfoList = kvManager.getConnectedDevicesInfo(DeviceFilterStrategy.NO_FILTER); - List
deviceIdList = new ArrayList<>(); - for (DeviceInfo deviceInfo : deviceInfoList) {
- deviceIdList.add(deviceInfo.getId());
- }
- singleKvStore.sync(deviceIdList, SyncMode.PUSH_ONLY);
項目中采用在后臺service中開啟定時任務(wù),實時保存數(shù)據(jù)到分布式數(shù)據(jù)庫,然后在主界面,監(jiān)聽數(shù)據(jù)變化,實時更新數(shù)據(jù)。
結(jié)果演示
1.剛開始安裝完成后效果:
2.每隔3秒,界面數(shù)據(jù)都會發(fā)生變化:
附上源碼:
1.MainAbilitySlice
- public class MainAbilitySlice extends AbilitySlice {
- private SingleKvStore singleKvStore;
- private Text tvTemp;
- private Text tvHumi;
- private Text tvGas;
- private Intent serviceIntent;
- private InnerKvStoreObserver innerKvStoreObserver;
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
- tvTemp=(Text)findComponentById(ResourceTable.Id_tvTemp);
- tvHumi=(Text)findComponentById(ResourceTable.Id_tvHumi);
- tvGas=(Text)findComponentById(ResourceTable.Id_tvGas);
- initService();
- try {
- //獲取數(shù)據(jù)庫
- singleKvStore = DBUtils.initOrGetDB(this, DBUtils.STORE_ID);
- innerKvStoreObserver = new InnerKvStoreObserver();
- singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, innerKvStoreObserver);
- } catch (KvStoreException e) {
- e.printStackTrace();
- }
- }
- public class InnerKvStoreObserver implements KvStoreObserver {
- @Override
- public void onChange(ChangeNotification changeNotification) {
- //刷新頁面上的數(shù)據(jù),同樣有一個坑,onChange方法實質(zhì)上,在一個子線程里執(zhí)行
- getUITaskDispatcher().asyncDispatch(() -> {
- //在這里執(zhí)行頁面ui組件的顯示刷新
- flushUIData();
- });
- }
- }
- private void flushUIData() {
- //查詢分布式數(shù)據(jù)的數(shù)據(jù)
- List
entries = singleKvStore.getEntries("key"); - if (entries.size() > 0) {
- ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString());
- int temp = zsonObject.getIntValue("temp");
- int humidity = zsonObject.getIntValue("humidity");
- int other = zsonObject.getIntValue("other");
- tvTemp.setText(temp+"℃");
- tvHumi.setText(humidity+"% RH");
- tvGas.setText(other+"% LEL");
- }
- }
- private void initService() {
- //啟動ServiceAbility
- serviceIntent = new Intent();
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId("")
- .withBundleName("com.isoftstone.kvstoreapp")
- .withAbilityName("com.isoftstone.kvstoreapp.ServiceAbility")
- .build();
- serviceIntent.setOperation(operation);
- startAbility(serviceIntent);
- }
- @Override
- public void onActive() {
- super.onActive();
- }
- @Override
- public void onForeground(Intent intent) {
- super.onForeground(intent);
- }
- @Override
- protected void onStop() {
- super.onStop();
- //銷毀service
- stopAbility(serviceIntent);
- //刪除數(shù)據(jù)庫
- DBUtils.clearDB();
- //解除訂閱
- if (singleKvStore != null) {
- singleKvStore.unSubscribe(innerKvStoreObserver);
- }
- }
- }
2.ServiceAbility
- public class ServiceAbility extends Ability {
- private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
- private SingleKvStore singleKvStore;
- private Timer timer;
- private MyTimerTask myTimerTask;
- private int temperature;
- private int humidity;
- private int gas;
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- singleKvStore = DBUtils.initOrGetDB(this, DBUtils.STORE_ID);
- timer=new Timer();
- myTimerTask=new MyTimerTask();
- timer.schedule(myTimerTask,0,3000);
- }
- @Override
- public void onBackground() {
- super.onBackground();
- HiLog.info(LABEL_LOG, "ServiceAbility::onBackground");
- }
- @Override
- public void onStop() {
- super.onStop();
- if(myTimerTask!=null){
- myTimerTask.cancel();
- }
- if(timer!=null){
- timer.cancel();
- }
- }
- @Override
- public void onCommand(Intent intent, boolean restart, int startId) {
- }
- @Override
- public IRemoteObject onConnect(Intent intent) {
- return null;
- }
- @Override
- public void onDisconnect(Intent intent) {
- }
- private class MyTimerTask extends TimerTask{
- @Override
- public void run() {
- temperature++;
- humidity++;
- gas++;
- try {
- long id = System.currentTimeMillis();
- singleKvStore.putString("key",
- "{\"id\":" + id +
- ",\"temp\":" + temperature +
- ",\"humidity\":" + humidity +
- ",\"NH4\":" + 0.0 +
- ",\"H2S\":" + 0.0 +
- ",\"other\":" + gas + "}");
- } catch (KvStoreException e) {
- e.printStackTrace();
- }
- }
- }
- }
3.DBUtils
- public class DBUtils {
- //分布式數(shù)據(jù)庫storeId
- public static final String STORE_ID="kvStoreDB";
- private static KvManager kvManager;
- private static SingleKvStore singleKvStore;
- //具體的實現(xiàn)數(shù)據(jù)庫的初始化
- public static SingleKvStore initOrGetDB(Context context, String storeId) {
- KvManagerConfig kvManagerConfig = new KvManagerConfig(context);
- kvManager = KvManagerFactory.getInstance().createKvManager(kvManagerConfig);
- Options options = new Options();
- options.setCreateIfMissing(true)
- .setEncrypt(false)
- .setKvStoreType(KvStoreType.SINGLE_VERSION)
- .setAutoSync(true);//設(shè)置數(shù)據(jù)為自動同步
- singleKvStore = kvManager.getKvStore(options, storeId);
- return singleKvStore;
- }
- // 如果數(shù)據(jù)庫中的字段有修改,只能先關(guān)閉,后刪除,然后重新創(chuàng)建才生效
- public static void clearDB() {
- kvManager.closeKvStore(singleKvStore);
- kvManager.deleteKvStore(STORE_ID);
- }
- }
4. MainAbility
- public class MainAbility extends Ability {
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setMainRoute(MainAbilitySlice.class.getName());
- //實現(xiàn)Ability的代碼中顯式聲明需要使用多設(shè)備協(xié)同訪問的權(quán)限
- requestPermissionsFromUser(new String[]{
- "ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
- }
- }
5. MyApplication
- public class MyApplication extends AbilityPackage {
- @Override
- public void onInitialize() {
- super.onInitialize();
- }
- }
6. config.json 文件
- {
- "app": {
- "bundleName": "com.isoftstone.healthdata",
- "vendor": "isoftstone",
- "version": {
- "code": 1000000,
- "name": "1.0"
- },
- "apiVersion": {
- "compatible": 4,
- "target": 5,
- "releaseType": "Release"
- }
- },
- "deviceConfig": {},
- "module": {
- "package": "com.isoftstone.kvstoreapp",
- "name": ".MyApplication",
- "deviceType": [
- "phone"
- ],
- "distro": {
- "deliveryWithInstall": true,
- "moduleName": "entry",
- "moduleType": "entry"
- },
- "reqPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ],
- "abilities": [
- {
- "skills": [
- {
- "entities": [
- "entity.system.home"
- ],
- "actions": [
- "action.system.home"
- ]
- }
- ],
- "orientation": "unspecified",
- "name": "com.isoftstone.kvstoreapp.MainAbility",
- "icon": "$media:icon",
- "description": "$string:mainability_description",
- "label": "$string:app_name",
- "type": "page",
- "launchType": "standard"
- },
- {
- "name": "com.isoftstone.kvstoreapp.ServiceAbility",
- "icon": "$media:icon",
- "description": "$string:serviceability_description",
- "type": "service"
- }
- ]
- }
- }
7.xml布局文件
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
- ohos:height="match_parent"
- ohos:orientation="vertical"
- ohos:width="match_parent">
- ohos:padding="20vp"
- ohos:height="match_content"
- ohos:width="match_parent"
- ohos:orientation="horizontal">
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text_size="20vp"
- ohos:text="溫度:"/>
- ohos:id="$+id:tvTemp"
- ohos:width="0"
- ohos:height="match_content"
- ohos:text_size="22vp"
- ohos:text_color="#00ff00"
- ohos:text="待采集..."
- ohos:weight="1"/>
- ohos:height="1vp"
- ohos:width="match_parent"
- ohos:background_element="#cccccc"/>
- ohos:padding="20vp"
- ohos:height="match_content"
- ohos:width="match_parent"
- ohos:orientation="horizontal">
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text_size="20vp"
- ohos:text="濕度:"/>
- ohos:id="$+id:tvHumi"
- ohos:width="0"
- ohos:height="match_content"
- ohos:text_size="22vp"
- ohos:text_color="#00ff00"
- ohos:text="待采集..."
- ohos:weight="1"/>
- ohos:height="1vp"
- ohos:width="match_parent"
- ohos:background_element="#cccccc"/>
- ohos:padding="20vp"
- ohos:height="match_content"
- ohos:width="match_parent"
- ohos:orientation="horizontal">
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text_size="20vp"
- ohos:text="可燃?xì)怏w:"/>
- ohos:id="$+id:tvGas"
- ohos:width="0"
- ohos:height="match_content"
- ohos:text_size="22vp"
- ohos:text_color="#00ff00"
- ohos:text="待采集..."
- ohos:weight="1"/>
- ohos:height="1vp"
- ohos:width="match_parent"
- ohos:background_element="#cccccc"/>
文章題目:HarmonyOS基礎(chǔ)技術(shù)賦能之分布式數(shù)據(jù)服務(wù)功能
URL鏈接:http://www.dlmjj.cn/article/ccdiseh.html


咨詢
建站咨詢
