HarmonyOSJS分布式能力—學(xué)習(xí)筆記
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
JS也是具有分布式能力的,本文就以兩個(gè)小項(xiàng)目來分享JS的分布式拉起和分布式遷移♪(∇*)
正文
這是從官網(wǎng)中找到的分布式API在FA生命周期中的位置圖,圖中的onStartContinuation()、onSaveData(OBJECT)、onRestoreData(OBJECT)和onCompleteContinuation(code)均為分布式能力接口

項(xiàng)目相同的操作:
1. 安裝和配置DevEco Studio 2.1 Release
DevEco Studio 2.1 Release下載、DevEco Studio 2.1 Release安裝
2. 創(chuàng)建一個(gè)Empty Java Phone應(yīng)用
DevEco Studio下載安裝成功后,打開DevEco Studio,點(diǎn)擊左上角的File,點(diǎn)擊New,再選擇New Project,選擇Empty Ability(Java)選項(xiàng),點(diǎn)擊Next按鈕。

分布式拉起將文件命名為Distributrd1,分布式遷移將文件命名為Distributrd2(文件名不能出現(xiàn)中文或者特殊字符,否則將無法成功創(chuàng)建項(xiàng)目文件),選擇保存路徑,選擇API5,設(shè)備勾選Phonet,最后點(diǎn)擊Finish按鈕。

3. 準(zhǔn)備工作
在entry>src>main>config.json文件中最下方"launchType": "standard"的后面添加以下代碼,這樣就可以實(shí)現(xiàn)去掉應(yīng)用上方的標(biāo)簽欄了。
config.json部分代碼:
- "name": "com.test.distributed1.MainAbility",
- "icon": "$media:icon",
- "description": "$string:mainability_description",
- "label": "$string:entry_MainAbility",
- "type": "page",
- "launchType": "standard",
- "metaData": {
- "customizeData": [
- {
- "name": "hwc-theme",
- "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar",
- "extra": ""
- }
- ]
- }
- }
- ],
- "js": [
- {
- "pages": [
- "pages/index/index"
- ],
- "name": "default",
- "window": {
- "designWidth": 720,
- "autoDesignWidth": true
- }
- }
- ]
- }
- }
4. 添加權(quán)限
在config.json中添加權(quán)限。
- "reqPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ],
在MainAbility.java中動(dòng)態(tài)申請權(quán)限。
- public class MainAbility extends AceAbility {
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- // 動(dòng)態(tài)判斷權(quán)限
- if (verifySelfPermission("ohos.permission.DISTRIBUTED_DATASYNC") != IBundleManager.PERMISSION_GRANTED) {
- // 應(yīng)用未被授予權(quán)限
- if (canRequestPermission("ohos.permission.DISTRIBUTED_DATASYNC")) {
- // 是否可以申請彈框授權(quán)(首次申請或者用戶未選擇禁止且不再提示)
- requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
- }
- }
- }
- @Override
- public void onStop() {
- super.onStop();
- }
- }
分布式拉起
效果圖
1. 實(shí)現(xiàn)界面布局
在index.hml中編寫以下代碼。
添加兩個(gè)button組件,類選擇器名均為btn,分別添加一個(gè)單擊事件,按鈕上的文本分別為“加1”和“拉起”。
- <div class="container">
- <text class="title">
- {{ title }}
- </text>
- <button class="btn" onclick="plus">加1</button>
- <button class="btn" onclick="distributed">拉起</button>
- </div>
在index.css中編寫以下代碼。
添加類選擇器btn,并修改其屬性值。
- .container {
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- .title {
- font-size: 40px;
- color: #000000;
- opacity: 0.9;
- }
- .btn {
- height: 60px;
- width: 100px;
- font-size: 40px;
- background-color: aquamarine;
- margin: 10px;
- }
2. 實(shí)現(xiàn)分布式拉起
在index.js中編寫以下代碼。
分布式拉起允許拉起一個(gè)本地或遠(yuǎn)程的FA,拉起時(shí)可以傳遞參數(shù)。添加按鈕點(diǎn)擊事件distributed()通過FeatureAbility.startAbility(OBJECT)方法拉起一個(gè)FA,無回調(diào)結(jié)果,允許以顯式的方式,拉起遠(yuǎn)程或本地的FA。
其中OBJECT為RequestParams類型的參數(shù),包含必填的bundleName(要啟動(dòng)的包名。需和abilityName配合使用,區(qū)分大小寫)、abilityName(要啟動(dòng)的ability名,區(qū)分大小寫)和選填的entities(希望被調(diào)起的FA所歸屬的實(shí)體列表,如果不填,默認(rèn)查找所有實(shí)體列表。需配合action使用)、action(在不指定包名及ability名的情況下,可以通過傳入action值從而根據(jù)Operation的其他屬性啟動(dòng)應(yīng)用)、deviceType(默認(rèn)0: 從本地以及遠(yuǎn)端設(shè)備中選擇要啟動(dòng)的FA。1: 從本地設(shè)備啟動(dòng)FA。有多個(gè)FA滿足條件的情況下,將彈框由用戶選擇設(shè)備)、data(指定要傳遞給對方的參數(shù),需要可被序列化)、flag(拉起FA時(shí)的配置開關(guān),如是否免安裝等)、url(拉起FA時(shí),指定打開的頁面的url。默認(rèn)直接打開首頁)。
- export default {
- data: {
- title: "0"
- },
- onInit() {
- },
- distributed(){
- let target = {
- bundleName: "com.test.distributed1",
- abilityName: "com.test.distributed1.MainAbility"
- };
- let result = FeatureAbility.startAbility(target);
- },
- }
3. 實(shí)現(xiàn)帶數(shù)據(jù)傳遞的分布式拉起
定義一個(gè)全局變量sum,并初始化為0。添加一個(gè)按鈕點(diǎn)擊事件plus()實(shí)現(xiàn)加1功能。
在FeatureAbility.startAbility(OBJECT)中添加一個(gè)參數(shù)data并實(shí)例化sum。
因?yàn)樗性赿ata中設(shè)置的字段,在對端FA中均可以直接在 this下拿到,所以在生命周期事件onInit()中通過this.number取得該值。
- var sum = 0;
- export default {
- data: {
- title: "0"
- },
- onInit() {
- sum = this.number;
- this.title = sum;
- },
- distributed(){
- let actionData = {
- number: sum
- };
- let target = {
- bundleName: "com.test.distributed1",
- abilityName: "com.test.distributed1.MainAbility",
- data: actionData
- };
- let result = FeatureAbility.startAbility(target);
- },
- plus(){
- sum++;
- this.title = sum;
- }
- }
分布式遷移
效果圖
1. 實(shí)現(xiàn)界面布局
創(chuàng)建一個(gè)名為Distributed2的Empty JS Phone空應(yīng)用。

在index.hml中編寫以下代碼。
添加兩個(gè)button組件,類選擇器名均為btn,分別添加一個(gè)單擊事件,按鈕上的文本分別為“加1”和“遷移”。
- <div class="container">
- <text class="title">
- {{ title }}
- </text>
- <button class="btn" onclick="plus">加1</button>
- <button class="btn" onclick="distributed">拉起</button>
- </div>
在index.css中編寫以下代碼。
添加類選擇器btn,并修改其屬性值。
- .container {
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- .title {
- font-size: 40px;
- color: #000000;
- opacity: 0.9;
- }
- .btn {
- height: 60px;
- width: 100px;
- font-size: 40px;
- background-color: aquamarine;
- margin: 10px;
- }
2. 實(shí)現(xiàn)分布式遷移
在index.js中編寫以下代碼。
分布式遷移提供了一個(gè)主動(dòng)遷移接口及一系列頁面生命周期回調(diào),以支持將本地業(yè)務(wù)無縫遷移到指定設(shè)備中。添加按鈕點(diǎn)擊事件distributed()通過FeatureAbility.continueAbility()方法主動(dòng)進(jìn)行FA遷移的入口。
其中onStartContinuation()為FA發(fā)起遷移時(shí)的回調(diào),在此回調(diào)中應(yīng)用可以根據(jù)當(dāng)前狀態(tài)決定是否遷移。返回值為Boolean類型,true表示允許進(jìn)行遷移,false表示不允許遷移。
onSaveData(OBJECT)為保存狀態(tài)數(shù)據(jù)的回調(diào),開發(fā)者需要往參數(shù)對象中填入需遷移到目標(biāo)設(shè)備上的數(shù)據(jù)。參數(shù)為可被序列化的自定義數(shù)據(jù)。
onRestoreData(OBJECT)為恢復(fù)發(fā)起遷移時(shí)onSaveData方法保存的數(shù)據(jù)的回調(diào),用于恢復(fù)應(yīng)用狀態(tài)的對象,其中的數(shù)據(jù)及結(jié)構(gòu)由onSaveData決定。
onCompleteContinuation(code)為遷移完成的回調(diào),在調(diào)用端被觸發(fā),表示應(yīng)用遷移到目標(biāo)設(shè)備上的結(jié)果。參數(shù)為遷移完成的結(jié)果。0:成功,-1:失敗。
- export default {
- data: {
- title: "0"
- },
- onStartContinuation() { // 判斷當(dāng)前的狀態(tài)是不是適合遷移
- console.info("onStartContinuation被調(diào)用,適合遷移");
- return true;
- },
- onCompleteContinuation(code) { // 遷移操作完成,code返回結(jié)果
- if(code == 0){
- console.info("onCompleteContinuation(code)被調(diào)用,遷移成功");
- } else if(code == -1){
- console.info("onCompleteContinuation(code)被調(diào)用,遷移失敗");
- }
- },
- onSaveData(saveData) { // 數(shù)據(jù)保存到savedData中進(jìn)行遷移。
- console.info("onSaveData(saveData)被調(diào)用");
- },
- onRestoreData(restoreData) { // 收到遷移數(shù)據(jù),恢復(fù)。
- console.info("onRestoreData(restoreData)被調(diào)用");
- },
- distributed(){
- let result = FeatureAbility.continueAbility();
- }
- }
3. 實(shí)現(xiàn)帶數(shù)據(jù)傳遞的分布式遷移
定義一個(gè)序列化continueAbilityData,其中的number為0。添加一個(gè)按鈕點(diǎn)擊事件plus()實(shí)現(xiàn)加1功能。
在onSaveData(saveData)函數(shù)中將序列化continueAbilityData保存到savedData中進(jìn)行遷移。在onRestoreData(restoreData)函數(shù)中將遷移的數(shù)據(jù)顯示出來。
- export default {
- data: {
- title: "0",
- continueAbilityData: {
- number: 0
- }
- },
- onStartContinuation() { // 判斷當(dāng)前的狀態(tài)是不是適合遷移
- console.info("onStartContinuation被調(diào)用,適合遷移");
- return true;
- },
- onCompleteContinuation(code) { // 遷移操作完成,code返回結(jié)果
- if(code == 0){
- console.info("onCompleteContinuation(code)被調(diào)用,遷移成功");
- } else if(code == -1){
- console.info("onCompleteContinuation(code)被調(diào)用,遷移失敗");
- }
- },
- onSaveData(saveData) { // 數(shù)據(jù)保存到savedData中進(jìn)行遷移。
- var data = this.continueAbilityData;
- Object.assign(saveData, data)
- console.info("onSaveData(saveData)被調(diào)用");
- },
- onRestoreData(restoreData) { // 收到遷移數(shù)據(jù),恢復(fù)。
- this.continueAbilityData = restoreData;
- this.title = this.continueAbilityData.number;
- console.info("onRestoreData(restoreData)被調(diào)用");
- },
- distributed(){
- let result = FeatureAbility.continueAbility();
- },
- plus(){
- this.continueAbilityData.number++;
- this.title = this.continueAbilityData.number;
- }
- }
寫在最后
本項(xiàng)目會(huì)長期更新 ,希望隨著鴻蒙一同成長變強(qiáng)的既有我們,也有正在看著這個(gè)項(xiàng)目的你。明年3月,深大校園內(nèi)的木棉花會(huì)盛開,那時(shí),鴻蒙也會(huì)變的更好,愿這花開,有你我的一份。
文章相關(guān)附件可以點(diǎn)擊下面的原文鏈接前往下載
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)