如何使用分布式数据库方法详解

奶盖
发布于 2021-7-20 10:54
浏览
2收藏

1. 如何使用分布式数据库

 

介绍

 

分布式数据服务(Distributed Data Service,DDS) 为应用程序提供不同设备间数据库数据分布式的能力。通过调用分布式数据接口,应用程序将数据保存到分布式数据库中。通过结合帐号、应用和数据库三元组,分布式数据服务对属于不同的应用的数据进行隔离,保证不同应用之间的数据不能通过分布式数据服务互相访问。在通过可信认证的设备间,分布式数据服务支持应用数据相互同步,为用户提供在多种终端设备上一致的数据访问体验。
有关分布式数据服务更加详细的介绍可以参考分布式数据服务
本教程将为您完整介绍以下内容并展示完整示例:

  1. 分布式数据库的创建
  2. 分布式数据库的插入和删除
  3. 分布式数据库的数据同步

 

 说明:
实现分布式数据库,需要至少两个设备处于同一个分布式网络中,可以通过操作如下配置实现:

所有设备接入同一网络,
所有设备登陆相同华为账号,
所有设备上开启“设置->更多连接->多设备协同 ”

 

2. 实现分布式数据库需要申请的权限

 

为了实现分布式数据库,需要在entry\src\main\config.json中申请ohos.permission.DISTRIBUTED_DATASYNC权限,以便允许不同设备间的数据交换。示例代码如下:

module": { 
...... 
   "reqPermissions": [ 
     { 
       "name": "ohos.permission.DISTRIBUTED_DATASYNC" 
     } 
  ] 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

 

3. 如何创建分布式数据库

 

要创建分布式数据库,首先要做的就是创建分布式数据库管理器实例KvManager,我们定义了如下方法:

private KvManager createManager() { 
	KvManager manager = null; 
	try { 
		KvManagerConfig config = new KvManagerConfig(this); 
		manager = KvManagerFactory.getInstance().createKvManager(config); 
	} 
	catch (KvStoreException exception) { 
		HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "some exception happen"); 
	} 
	return manager; 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

 

创建成功后,借助KvManager创建SINGLE_VERSION分布式数据库,方法如下:

private SingleKvStore createDb(KvManager kvManager) { 
	SingleKvStore kvStore = null; 
	try { 
		Options options = new Options(); 
		options.setCreateIfMissing(true).setEncrypt(false).setKvStoreType(KvStoreType.SINGLE_VERSION); 
		kvStore = kvManager.getKvStore(options, STORE_ID); 
	} catch (KvStoreException exception) { 
		HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "some exception happen"); 
	} 
	return kvStore; 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

 

说明:
SINGLE_VERSION分布式数据库是指数据在本地保存是以单个KV条目为单位的方式保存,对每个Key最多只保存一个条目项,当数据在本地被用户修改时,不管它是否已经被同步出去,均直接在这个条目上进行修改。

 

最后是订阅分布式数据库中数据变化,方法如下:

private void subscribeDb(SingleKvStore singleKvStore) { 
    KvStoreObserver kvStoreObserverClient = new KvStoreObserverClient(); 
    singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_REMOTE, kvStoreObserverClient); 
}
  • 1.
  • 2.
  • 3.
  • 4.

 

4. 如何进行数据查询、插入和删除

 

数据插入

 

在将数据写入分布式数据库之前,需要先构造分布式数据库的Key(键)和Value(值),通过putString方法将数据写入到数据库中,具体示例如下:

private void writeData(String key, String value) { 
    if (key == null || key.isEmpty() || value == null || value.isEmpty()) { 
        return; 
    } 
    singleKvStore.putString(key, value); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 

 

数据查询

 

分布式数据库中的数据查询是根据Key(键)来进行的,如果指定Key(键),则会查询出对应Key(键)的数据;如果不指定Key,既为空,则查询出所有数据,查询示例代码如下

private void queryContact() { 
	List entryList = singleKvStore.getEntries(""); 
	contactArray.clear(); 
	try { 
		for (Entry entry : entryList) { 
			contactArray.add(new Contacter(entry.getValue().getString(), entry.getKey())); 
		} 
	} catch (KvStoreException exception) { 
		HiLog.info(LABEL_LOG, LOG_FORMAT,TAG,"the value must be String"); 
	} 
	contactAdapter.notifyDataChanged(); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

 

 说明:
以上代码除查询外,还有部分场景业务代码。

 

数据删除

 

对于分布式数据库的删除操作,可以直接调用deleteKvStore()方法,但是需要传递事先定义好的STORE_ID参数(具体定义参考下文完整代码),示例代码如下:

@Override 
protected void onStop() { 
    super.onStop(); 
    kvManager.closeKvStore(singleKvStore); 
    kvManager.deleteKvStore(STORE_ID); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 

5. 如何进行分布式数据库的同步

 

在进行数据同步之前,首先需要先获取当前组网环境中的设备列表,然后指定同步方式(PULL_ONLY,PUSH_ONLY,PUSH_PULL)进行同步,以PUSH_PULL方式为例,示例代码如下:

private void syncContact() { 
    List<DeviceInfo> deviceInfoList = kvManager.getConnectedDevicesInfo(DeviceFilterStrategy.NO_FILTER); 
    List<String> deviceIdList = new ArrayList<>(); 
    for (DeviceInfo deviceInfo : deviceInfoList) { 
        deviceIdList.add(deviceInfo.getId()); 
    } 
    HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "device size= " + deviceIdList.size()); 
    if (deviceIdList.size() == 0) { 
        showTip("组网失败"); 
        return; 
    } 
    singleKvStore.registerSyncCallback(new SyncCallback() { 
        @Override 
        public void syncCompleted(Map<String, Integer> map) { 
            getUITaskDispatcher().asyncDispatch(new Runnable() { 
                @Override 
                public void run() { 
                    queryContact(); 
                    showTip("同步成功"); 
                } 
            }); 
            singleKvStore.unRegisterSyncCallback(); 
        } 
    }); 
    singleKvStore.sync(deviceIdList, SyncMode.PUSH_PULL); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

 

 说明:
以上代码除数据同步外,还有部分场景业务代码。

6. 最终实现效果如何使用分布式数据库方法详解-鸿蒙开发者社区如何使用分布式数据库方法详解-鸿蒙开发者社区

8. 示例代码

代码结构解读

 

为了方便您的学习,我们提供了的分布式数据库示例工程的完整代码,工程以一个简易的信息管理系统为背景,代码的工程结构如下:

  • Provider:ContactProvider为数据信息的适配器,主要作用为高效传递和使用相关数据。
  • Been:Contacter封装了联系人信息。
  • Componet:ContactComponent添加和修改信息的Dialog实现类。
  • Slice:ContactSlice应用主页面,分布式数据库逻辑实现类。

如何使用分布式数据库方法详解-鸿蒙开发者社区

 

除以上文件,工程中还用到了三个xml布局文件,他们声明在了main\resources\base\layout目录下。

编写布局和样式

 

首先在HUAWEI DevEco Studio创建一个Phone的Empty Feature Ability(Java)模板工程,然后在 "resources/layout"下新增三个布局。

 

ability_contact.xml:该布局定义了"同步"和"添加"两个Button,姓名、手机号码、信息管理三个Text,具体代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:height="match_parent" 
    ohos:width="match_parent" 
    ohos:orientation="vertical"> 
 
  <DependentLayout 
      ohos:width="match_parent" 
      ohos:height="60vp" 
      > 
    <Text 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text="信息管理" 
        ohos:text_color="#222222" 
        ohos:text_size="22fp" 
        ohos:center_in_parent="true" 
        /> 
    <Button 
        ohos:id="$+id:addContact" 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text="添加" 
        ohos:text_color="#a0a0a0" 
        ohos:text_size="18fp" 
        ohos:align_parent_right="true" 
        ohos:vertical_center="true" 
        ohos:right_margin="16vp" 
        /> 
    <Button 
        ohos:id="$+id:sync" 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text="同步" 
        ohos:text_color="#a0a0a0" 
        ohos:text_size="18fp" 
        ohos:align_parent_left="true" 
        ohos:vertical_center="true" 
        ohos:left_margin="16vp" 
        /> 
  </DependentLayout> 
  <Component 
      ohos:height="1vp" 
      ohos:width="match_parent" 
      ohos:background_element="#eeeeee" 
      /> 
  <DirectionalLayout 
      ohos:width="match_parent" 
      ohos:height="40vp" 
      ohos:orientation="horizontal" 
      > 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:id="$+id:name" 
        ohos:text="姓名" 
        ohos:text_color="#222222" 
        ohos:text_size="16fp" 
        ohos:weight="10" 
        ohos:text_alignment="center" 
        ohos:layout_alignment="center" 
        /> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:id="$+id:phone" 
        ohos:text="手机号码" 
        ohos:text_color="#555555" 
        ohos:text_size="16fp" 
        ohos:weight="10" 
        ohos:text_alignment="center" 
        ohos:layout_alignment="center" 
        /> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="40vp" 
        ohos:weight="7" 
        ohos:left_margin="20vp" 
        > 
    </Text> 
  </DirectionalLayout> 
  <ListContainer 
      ohos:id="$+id:listContainer" 
      ohos:width="match_parent" 
      ohos:height="match_parent" 
      ohos:orientation="vertical" 
      /> 
</DirectionalLayout>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.

 

item_contact.xml:该布局为新增信息后,每条信息后面的编辑和删除Button,具体代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:width="match_parent" 
    ohos:height="41vp" 
    ohos:orientation="vertical" 
    > 
  <DirectionalLayout 
      ohos:id="$+id:dir_id" 
      ohos:width="match_parent" 
      ohos:height="40vp" 
      ohos:orientation="horizontal" 
      > 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:id="$+id:name" 
        ohos:text_color="#222222" 
        ohos:text_size="16fp" 
        ohos:weight="10" 
        ohos:text_alignment="center" 
        ohos:layout_alignment="center" 
        /> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:id="$+id:phone" 
        ohos:text_color="#555555" 
        ohos:text_size="16fp" 
        ohos:weight="10" 
        ohos:text_alignment="center" 
        ohos:layout_alignment="center" 
        /> 
    <DirectionalLayout 
        ohos:width="match_parent" 
        ohos:height="40vp" 
        ohos:orientation="horizontal" 
        ohos:left_margin="20vp" 
        ohos:weight="7" 
        > 
      <Button 
          ohos:id="$+id:edit" 
          ohos:width="match_content" 
          ohos:height="match_content" 
          ohos:text="编辑" 
          ohos:text_color="#00dddd" 
          ohos:text_size="16fp" 
          ohos:padding="4vp" 
          ohos:layout_alignment="center" 
          /> 
      <Button 
          ohos:id="$+id:delete" 
          ohos:width="match_content" 
          ohos:height="match_content" 
          ohos:text="删除" 
          ohos:text_color="#cc0000" 
          ohos:text_size="16fp" 
          ohos:padding="4vp" 
          ohos:layout_alignment="center" 
          /> 
    </DirectionalLayout> 
  </DirectionalLayout> 
  <Text 
      ohos:width="match_parent" 
      ohos:height="1vp" 
      ohos:background_element="#aaeeeeee" 
      ohos:left_margin="20vp" 
      ohos:right_margin="20vp" 
      /> 
</DirectionalLayout>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.

 

item_dialog.xml:该布局为点击添加按钮后出现的Dialog,主要由姓名和手机号码TextFIeld,以及确认Button构成,具体示例代码如下

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:width="match_parent" 
    ohos:height="match_content" 
    ohos:orientation="vertical" 
    > 
    <Text 
        ohos:id="$+id:title" 
        ohos:width="match_content" 
        ohos:height="match_content" 
        ohos:text="添加信息" 
        ohos:text_color="#111111" 
        ohos:text_size="18fp" 
        ohos:layout_alignment="center" 
        ohos:top_margin="30vp" 
        ohos:bottom_margin="30vp" 
        /> 
    <DirectionalLayout 
        ohos:width="match_parent" 
        ohos:height="40vp" 
        ohos:orientation="horizontal" 
        ohos:left_margin="19vp" 
        ohos:right_margin="19vp" 
        > 
        <Text 
            ohos:width="match_parent" 
            ohos:height="match_content" 
            ohos:text="姓名:" 
            ohos:text_color="#222222" 
            ohos:text_size="16fp" 
            ohos:weight="1" 
            ohos:layout_alignment="vertical_center|left" 
            /> 
        <TextField 
            ohos:width="match_parent" 
            ohos:height="match_parent" 
            ohos:id="$+id:name" 
            ohos:text_color="#555555" 
            ohos:text_size="16fp" 
            ohos:weight="3" 
            ohos:hint="输入姓名" 
            ohos:background_element="$graphic:background_input" 
            ohos:text_alignment="vertical_center|left" 
            ohos:left_padding="10vp" 
            ohos:layout_alignment="center" 
            /> 
    </DirectionalLayout> 
 
    <DirectionalLayout 
        ohos:width="match_parent" 
        ohos:height="40vp" 
        ohos:orientation="horizontal" 
        ohos:left_margin="19vp" 
        ohos:right_margin="19vp" 
        ohos:top_margin="16vp" 
        > 
        <Text 
            ohos:width="match_parent" 
            ohos:height="match_content" 
            ohos:text="手机号码:" 
            ohos:text_color="#222222" 
            ohos:text_size="16fp" 
            ohos:weight="1" 
            ohos:layout_alignment="vertical_center|left" 
            /> 
        <TextField 
            ohos:width="match_parent" 
            ohos:height="match_parent" 
            ohos:id="$+id:phone" 
            ohos:text_color="#555555" 
            ohos:text_size="16fp" 
            ohos:weight="3" 
            ohos:hint="输入手机号" 
            ohos:background_element="$graphic:background_input" 
            ohos:text_alignment="vertical_center|left" 
            ohos:left_padding="10vp" 
            ohos:layout_alignment="center" 
            /> 
    </DirectionalLayout> 
    <Button 
        ohos:id="$+id:confirm" 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="确认" 
        ohos:text_color="#ffffff" 
        ohos:text_size="16fp" 
        ohos:layout_alignment="center" 
        ohos:left_margin="30vp" 
        ohos:right_margin="30vp" 
        ohos:top_margin="40vp" 
        ohos:bottom_margin="40vp" 
        ohos:bottom_padding="10vp" 
        ohos:top_padding="10vp" 
        ohos:background_element="$graphic:background_button" 
        /> 
</DirectionalLayout>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.

 

随后在“resources/base/graphic/”目录下增加如下文件:

 

background_input.xml文件用来定义Input背景属性,示例代码如下:

<?xml version="1.0" encoding="UTF-8" ?> 
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos" 
       ohos:shape="rectangle"> 
    <corners 
        ohos:radius="8vp"/> 
    <solid 
        ohos:color="#00000000"/> 
    <stroke ohos:width="1vp" ohos:color="#eeeeee"/> 
</shape>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

background_button.xml文件用来定义Button背景属性,示例代码如下:

<?xml version="1.0" encoding="UTF-8" ?> 
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos" 
       ohos:shape="rectangle"> 
 
    <corners 
        ohos:radius="8vp"/> 
    <solid 
        ohos:color="#00dddd"/> 
</shape>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

业务逻辑代码

 

在"entry\src\main\java\com\huawei\codelab\provider"下新增ContactProvider.Java文件,该类的主要作用是提高使用和编辑数据的效率,示例代码如下:

import com.huawei.cookbooks.ResourceTable; 
import com.huawei.cookbooks.been.Contacter; 
 
import ohos.agp.components.BaseItemProvider; 
import ohos.agp.components.Button; 
import ohos.agp.components.Component; 
import ohos.agp.components.ComponentContainer; 
import ohos.agp.components.LayoutScatter; 
import ohos.agp.components.Text; 
import ohos.app.Context; 
 
import java.util.List; 
 
/** 
 * Contact List Adapter   
 */ 
public class ContactProvider extends BaseItemProvider { 
    private List contactArray; 
 
    private Context context; 
 
    private AdapterClickListener adapterClickListener; 
 
    public ContactProvider(Context context, List contactArray) { 
        this.context = context; 
        this.contactArray = contactArray; 
    } 
 
    @Override 
    public int getCount() { 
        return contactArray == null ? 0 : contactArray.size(); 
    } 
 
    @Override 
    public Object getItem(int position) { 
        if (position < contactArray.size() && position >= 0) { 
            return contactArray.get(position); 
        } 
        return null; 
    } 
 
    @Override 
    public long getItemId(int position) { 
        return position; 
    } 
 
    /** 
     * Component of each item 
     * 
     * @param position Index 
     * @param componentPara Reused Component 
     * @param componentContainer Container 
     * @return Component of each item 
     */ 
    @Override 
    public Component getComponent(int position, Component componentPara, ComponentContainer componentContainer) { 
        ViewHolder viewHolder = null; 
        Component component = componentPara; 
        if (component == null) { 
            component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_contact, 
                    null, false); 
            viewHolder = new ViewHolder(); 
            Component componentText = component.findComponentById(ResourceTable.Id_name); 
            if (componentText instanceof Text) { 
                viewHolder.name = (Text) componentText; 
            } 
            componentText = component.findComponentById(ResourceTable.Id_phone); 
            if (componentText instanceof Text) { 
                viewHolder.phone = (Text) componentText; 
            } 
            viewHolder.delete = (Button) component.findComponentById(ResourceTable.Id_delete); 
            viewHolder.edit = (Button) component.findComponentById(ResourceTable.Id_edit); 
            component.setTag(viewHolder); 
        } else { 
            if (component.getTag() instanceof ViewHolder) { 
                viewHolder = (ViewHolder) component.getTag(); 
            } 
        } 
        if (viewHolder != null) { 
            viewHolder.name.setText(contactArray.get(position).getName()); 
            viewHolder.phone.setText(contactArray.get(position).getPhone()); 
            viewHolder.edit.setClickedListener(new Component.ClickedListener() { 
                @Override 
                public void onClick(Component component) { 
                    if (adapterClickListener != null) { 
                        adapterClickListener.edit(position); 
                    } 
                } 
            }); 
            viewHolder.delete.setClickedListener(new Component.ClickedListener() { 
                @Override 
                public void onClick(Component component) { 
                    if (adapterClickListener != null) { 
                        adapterClickListener.delete(position); 
                    } 
                } 
            }); 
        } 
        return component; 
    } 
 
    private static class ViewHolder { 
        private Text name; 
        private Text phone; 
        private Button edit; 
        private Button delete; 
    } 
 
    /** 
     * Defines the callback event interface. 
     */ 
    public interface AdapterClickListener { 
        void edit(int position); 
 
        void delete(int position); 
    } 
 
    public void setAdapterClickListener(AdapterClickListener adapterClickListener) { 
        this.adapterClickListener = adapterClickListener; 
    } 
} 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.

 

在"entry\src\main\java\com\huawei\codelab\been"下新增Contacter.Java文件,该类的主要作用是封装姓名和电话号信息,示例代码如下:

public class Contacter { 
    private String name; 
 
    private String phone; 
 
    public Contacter(String name, String phone) { 
        this.name = name; 
        this.phone = phone; 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public String getPhone() { 
        return phone; 
    } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

 

在"entry\src\main\java\com\huawei\codelab\componet"下新增ContactComponent.Java文件,该类的主要作用是整合添加数据时dialog用到的组件以及初始化部分数据,示例代码如下:

import com.huawei.cookbooks.ResourceTable; 
 
import ohos.agp.components.Component; 
import ohos.agp.components.DirectionalLayout; 
import ohos.agp.components.LayoutScatter; 
import ohos.agp.components.Text; 
import ohos.agp.components.TextField; 
import ohos.app.Context; 
 
/** 
 * add/edit contact layout 
 */ 
public class ContactComponent extends DirectionalLayout { 
    private Component component; 
 
    private TextField nameTextField; 
 
    private TextField phoneTextField; 
 
    private Text title; 
 
    private DialogCallBack dialogCallBack; 
 
    public ContactComponent(Context context) { 
        super(context); 
        addComponent(context); 
        initView(); 
        initEvent(); 
    } 
 
    private void initEvent() { 
        component.findComponentById(ResourceTable.Id_confirm).setClickedListener(new Component.ClickedListener() { 
            @Override 
            public void onClick(Component component) { 
                confirmContact(); 
            } 
        }); 
    } 
 
    private void confirmContact() { 
        String nameInput = nameTextField.getText(); 
        String phoneInput = phoneTextField.getText(); 
        if (dialogCallBack != null) { 
            dialogCallBack.result(nameInput, phoneInput); 
        } 
    } 
 
    private void initView() { 
        Component componentText = component.findComponentById(ResourceTable.Id_name); 
        if (componentText instanceof TextField) { 
            nameTextField = (TextField) componentText; 
        } 
        componentText = component.findComponentById(ResourceTable.Id_phone); 
        if (componentText instanceof TextField) { 
            phoneTextField = (TextField) componentText; 
        } 
        componentText = component.findComponentById(ResourceTable.Id_title); 
        if (componentText instanceof Text) { 
            title = (Text) componentText; 
        } 
    } 
 
    private void addComponent(Context context) { 
        component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_dialog, 
                null, false); 
        addComponent(component); 
        LayoutConfig layoutConfig = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_CONTENT); 
        setLayoutConfig(layoutConfig); 
    } 
 
    public void initData(String name, String phone) { 
        nameTextField.setBubbleSize(0,0); 
        phoneTextField.setBubbleSize(0,0); 
        if (name != null) { 
            nameTextField.setText(name); 
        } 
        if (phone != null) { 
            phoneTextField.setText(phone); 
            phoneTextField.setEnabled(false); 
            title.setText("修改信息"); 
        } 
    } 
 
    public void setDialogCallBack(DialogCallBack dialogCallBack) { 
        this.dialogCallBack = dialogCallBack; 
    } 
 
    public interface DialogCallBack { 
        void result(String name, String phone); 
    } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.

 

 

在"entry\src\main\java\com\huawei\codelab\slice"下新增ContactSlice.Java文件,该类主要实现了分布式数据的创建,删除,和同步等操作以及部分业务逻辑,具体示例代码如下:

import com.huawei.cookbooks.ResourceTable; 
import com.huawei.cookbooks.been.Contacter; 
import com.huawei.cookbooks.component.ContactComponent; 
import com.huawei.cookbooks.provider.ContactProvider; 
 
import ohos.aafwk.ability.AbilitySlice; 
import ohos.aafwk.content.Intent; 
import ohos.agp.components.Component; 
import ohos.agp.components.ListContainer; 
import ohos.agp.utils.LayoutAlignment; 
import ohos.agp.window.dialog.CommonDialog; 
import ohos.agp.window.dialog.IDialog; 
import ohos.agp.window.dialog.ToastDialog; 
import ohos.data.distributed.common.*; 
import ohos.data.distributed.device.DeviceFilterStrategy; 
import ohos.data.distributed.device.DeviceInfo; 
import ohos.data.distributed.user.SingleKvStore; 
import ohos.hiviewdfx.HiLog; 
import ohos.hiviewdfx.HiLogLabel; 
 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
 
public class ContactSlice extends AbilitySlice implements ContactProvider.AdapterClickListener { 
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "HiContact"); 
 
    private static final String LOG_FORMAT = "%{public}s: %{public}s"; 
 
    private static final String TAG = "ContactSlice"; 
 
    private static final String STORE_ID = "contact_db1"; 
 
    private static final int DIALOG_SIZE_WIDTH = 800; 
 
    private static final int DIALOG_SIZE_HEIGHT = 800; 
 
    private static final int SHOW_TIME = 1500; 
 
    private ContactProvider contactAdapter; 
 
    private List contactArray; 
 
    private KvManager kvManager; 
 
    private SingleKvStore singleKvStore; 
 
    @Override 
    public void onStart(Intent intent) { 
        super.onStart(intent); 
        super.setUIContent(ResourceTable.Layout_ability_contact); 
        initDbManager(); 
        initList(); 
        initEvent(); 
        queryContact(); 
    } 
 
    /** 
     * Initialize click event 
     */ 
    private void initEvent() { 
        findComponentById(ResourceTable.Id_addContact).setClickedListener(new Component.ClickedListener() { 
            @Override 
            public void onClick(Component component) { 
                addContact(); 
            } 
        }); 
        findComponentById(ResourceTable.Id_sync).setClickedListener(new Component.ClickedListener() { 
            @Override 
            public void onClick(Component component) { 
                syncContact(); 
            } 
        }); 
    } 
 
    /** 
     * Initialize ListContainer 
     */ 
    private void initList() { 
        Component component = findComponentById(ResourceTable.Id_listContainer); 
        ListContainer listContainer; 
        if (component instanceof ListContainer) { 
            listContainer = (ListContainer) component; 
            contactArray = new ArrayList<>(); 
            contactAdapter = new ContactProvider(this, contactArray); 
            listContainer.setItemProvider(contactAdapter); 
            contactAdapter.setAdapterClickListener(this); 
        } 
    } 
 
    /** 
     * Synchronizing contacts data 
     */ 
    private void syncContact() { 
        List deviceInfoList = kvManager.getConnectedDevicesInfo(DeviceFilterStrategy.NO_FILTER); 
        List deviceIdList = new ArrayList<>(); 
        for (DeviceInfo deviceInfo : deviceInfoList) { 
            deviceIdList.add(deviceInfo.getId()); 
        } 
        HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "device size= " + deviceIdList.size()); 
        if (deviceIdList.size() == 0) { 
            showTip("组网失败"); 
            return; 
        } 
        singleKvStore.registerSyncCallback(new SyncCallback() { 
            @Override 
            public void syncCompleted(Map map) { 
                getUITaskDispatcher().asyncDispatch(new Runnable() { 
                    @Override 
                    public void run() { 
                        HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "sync success"); 
                        queryContact(); 
                        showTip("同步成功"); 
                    } 
                }); 
                singleKvStore.unRegisterSyncCallback(); 
            } 
        }); 
        singleKvStore.sync(deviceIdList, SyncMode.PUSH_PULL); 
    } 
 
    /** 
     * Initializing Database Management 
     */ 
    private void initDbManager() { 
        kvManager = createManager(); 
        singleKvStore = createDb(kvManager); 
        subscribeDb(singleKvStore); 
    } 
 
    /** 
     * Create a distributed database manager instance 
     * 
     * @return database manager 
     */ 
    private KvManager createManager() { 
        KvManager manager = null; 
        try { 
            KvManagerConfig config = new KvManagerConfig(this); 
            manager = KvManagerFactory.getInstance().createKvManager(config); 
        } 
        catch (KvStoreException exception) { 
            HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "some exception happen"); 
        } 
        return manager; 
    } 
 
    /** 
     * Creating a Single-Version Distributed Database 
     * 
     * @param kvManager Database management 
     * @return SingleKvStore 
     */ 
    private SingleKvStore createDb(KvManager kvManager) { 
        SingleKvStore kvStore = null; 
        try { 
            Options options = new Options(); 
            options.setCreateIfMissing(true).setEncrypt(false).setKvStoreType(KvStoreType.SINGLE_VERSION); 
            kvStore = kvManager.getKvStore(options, STORE_ID); 
        } catch (KvStoreException exception) { 
            HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "some exception happen"); 
        } 
        return kvStore; 
    } 
 
    /** 
     * Subscribing to All (Currently, Remote) Data Change Notifications of a Single-Version Distributed Database 
     * 
     * @param singleKvStore Data operation 
     */ 
    private void subscribeDb(SingleKvStore singleKvStore) { 
        KvStoreObserver kvStoreObserverClient = new KvStoreObserverClient(); 
        singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_REMOTE, kvStoreObserverClient); 
    } 
 
    /** 
     * Receive database messages 
     */ 
    private class KvStoreObserverClient implements KvStoreObserver { 
        @Override 
        public void onChange(ChangeNotification notification) { 
            getUITaskDispatcher().asyncDispatch(new Runnable() { 
                @Override 
                public void run() { 
                    HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "come to auto sync"); 
                    queryContact(); 
                    showTip("同步成功"); 
                } 
            }); 
        } 
    } 
 
    /** 
     * Query Local Contacts 
     */ 
    private void queryContact() { 
        List entryList = singleKvStore.getEntries(""); 
        HiLog.info(LABEL_LOG, LOG_FORMAT,TAG,"entryList size" + entryList.size()); 
        contactArray.clear(); 
        try { 
            for (Entry entry : entryList) { 
                contactArray.add(new Contacter(entry.getValue().getString(), entry.getKey())); 
            } 
        } catch (KvStoreException exception) { 
            HiLog.info(LABEL_LOG, LOG_FORMAT,TAG,"the value must be String"); 
        } 
        contactAdapter.notifyDataChanged(); 
    } 
 
    /** 
     * Write key-value data to the single-version distributed database. 
     * 
     * @param key Stored key 
     * @param value Stored value 
     */ 
    private void writeData(String key, String value) { 
        if (key == null || key.isEmpty() || value == null || value.isEmpty()) { 
            return; 
        } 
        singleKvStore.putString(key, value); 
        HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "writeContact key= " + key + " writeContact value= " + value); 
    } 
 
    /** 
     * Deleting Key Value Data from the Single-Version Distributed Database 
     * 
     * @param key Deleted Key 
     */ 
    private void deleteData(String key) { 
        if (key.isEmpty()) { 
            return; 
        } 
        singleKvStore.delete(key); 
        HiLog.info(LABEL_LOG, LOG_FORMAT,TAG, "deleteContact key= " + key); 
    } 
 
    /** 
     * Add Contact 
     */ 
    private void addContact() { 
        showDialog(null, null, new ContactComponent.DialogCallBack() { 
            @Override 
            public void result(String name, String phone) { 
                writeData(phone, name); 
                contactArray.add(new Contacter(name, phone)); 
                contactAdapter.notifyDataSetItemInserted(contactAdapter.getCount()); 
                queryContact(); 
            } 
        }); 
    } 
 
    /** 
     * Display dialog box 
     * 
     * @param name Contacts 
     * @param phone phone 
     * @param dialogCallBack callback result 
     */ 
    private void showDialog(String name, String phone, ContactComponent.DialogCallBack dialogCallBack) { 
        CommonDialog commonDialog = new CommonDialog(this); 
        ContactComponent component = new ContactComponent(this); 
        component.initData(name, phone); 
        component.setDialogCallBack(new ContactComponent.DialogCallBack() { 
            @Override 
            public void result(String nameInput, String phoneInput) { 
                if (nameInput.isEmpty() || phoneInput.isEmpty()) { 
                    showTip("姓名与手机号码必填"); 
                    return; 
                } 
 
                if (phone == null && phoneIsExist(phoneInput)) { 
                    showTip("手机号码已经存在了"); 
                    return; 
                } 
 
                if (dialogCallBack != null) { 
                    dialogCallBack.result(nameInput, phoneInput); 
                } 
                commonDialog.remove(); 
            } 
        }); 
 
        commonDialog.setAutoClosable(true); 
        commonDialog.setContentCustomComponent(component); 
        commonDialog.show(); 
    } 
 
    /** 
     * Check whether the mobile number exists 
     * 
     * @param phone phone 
     * @return boolean 
     */ 
    private boolean phoneIsExist(String phone) { 
        List entryList = singleKvStore.getEntries(""); 
        for (Entry entry : entryList) { 
            if (entry.getKey().equals(phone)) { 
                return true; 
            } 
        } 
        return false; 
    } 
 
    /** 
     * Event triggered by clicking each edit button 
     * 
     * @param position Position of the item number 
     */ 
    @Override 
    public void edit(int position) { 
        Contacter contacter = contactArray.get(position); 
        showDialog(contacter.getName(), contacter.getPhone(), new ContactComponent.DialogCallBack() { 
            @Override 
            public void result(String name, String phone) { 
                writeData(phone, name); 
                contactArray.set(position, new Contacter(name, phone)); 
                contactAdapter.notifyDataSetItemChanged(position); 
                queryContact(); 
            } 
        }); 
    } 
 
    /** 
     * Event triggered by clicking each delete button 
     * 
     * @param position Position of the item number 
     */ 
    @Override 
    public void delete(int position) { 
        CommonDialog commonDialog = new CommonDialog(this); 
        commonDialog.setSize(DIALOG_SIZE_WIDTH, DIALOG_SIZE_HEIGHT); 
        commonDialog.setAutoClosable(true); 
        commonDialog.setTitleText("    警告") 
                .setContentText("    确定要删除吗?") 
                .setButton(0, "取消", new IDialog.ClickedListener() { 
                    @Override 
                    public void onClick(IDialog iDialog, int i) { 
                        iDialog.destroy(); 
                    } 
                }) 
                .setButton(1, "确认", new IDialog.ClickedListener() { 
                    @Override 
                    public void onClick(IDialog iDialog, int i) { 
                        if (position > contactArray.size() - 1) { 
                            showTip("要删除的元素不存在"); 
                            return; 
                        } 
                        deleteData(contactArray.get(position).getPhone()); 
                        contactArray.remove(position); 
                        contactAdapter.notifyDataChanged(); 
                        showTip("删除成功"); 
                        iDialog.destroy(); 
                    } 
                }).show(); 
    } 
 
    /** 
     * tip message 
     * 
     * @param message message 
     */ 
    private void showTip(String message) { 
        new ToastDialog(this).setAlignment(LayoutAlignment.CENTER) 
                .setText(message).setDuration(SHOW_TIME).show(); 
    } 
 
    @Override 
    protected void onStop() { 
        super.onStop(); 
        kvManager.closeKvStore(singleKvStore); 
        kvManager.deleteKvStore(STORE_ID); 
    } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.
  • 339.
  • 340.
  • 341.
  • 342.
  • 343.
  • 344.
  • 345.
  • 346.
  • 347.
  • 348.
  • 349.
  • 350.
  • 351.
  • 352.
  • 353.
  • 354.
  • 355.
  • 356.
  • 357.
  • 358.
  • 359.
  • 360.
  • 361.
  • 362.
  • 363.
  • 364.
  • 365.
  • 366.
  • 367.
  • 368.
  • 369.
  • 370.
  • 371.
  • 372.
  • 373.

 

 

最后在MainAbility.Java文件中增加页面路由和动态权限申请,具体示例代码如下:

 
import ohos.aafwk.ability.Ability; 
import ohos.aafwk.content.Intent; 
import ohos.bundle.IBundleManager; 
 
import com.huawei.codelab.slice.ContactSlice; 
 
public class MainAbility extends Ability { 
    private static final String DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; 
 
    private static final int PERMISSION_CODE = 20201203; 
 
    @Override 
    public void onStart(Intent intent) { 
        super.onStart(intent); 
        super.setMainRoute(ContactSlice.class.getName()); 
        requestPermission(); 
    } 
 
    private void requestPermission() { 
        if (verifySelfPermission(DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) { 
            if (canRequestPermission(DISTRIBUTED_DATASYNC)) { 
                requestPermissionsFromUser( 
                        new String[]{DISTRIBUTED_DATASYNC}, PERMISSION_CODE); 
            } 
        } 
    } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

 

恭喜您
通过本教程的学习,您已经学会了分布式数据库服务的基础操作(创建、新增、删除、同步)。


 

 

 

已于2022-5-5 14:18:33修改
3
收藏 2
回复
举报
3
2
回复
    相关推荐