輕松玩轉(zhuǎn)HDC2021趣味闖關(guān)賽平行視界服務(wù)流轉(zhuǎn)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
一, 前言
此帖子是對參加HDC2021 Codelabs趣味闖關(guān)賽的總結(jié),此Demo是基于Codelabs里Java電影卡片基礎(chǔ)上開發(fā)的,添加了平行視界,服務(wù)流轉(zhuǎn)功能知識點(diǎn), 先說一下。
闖關(guān)賽題要求就是上面介紹的,我是24號才去參加Codelabs挑戰(zhàn)賽的, 23號一直呆在Harmony應(yīng)用與服務(wù)開發(fā)教室聽課, 晚上聽到參加了Codelabs挑戰(zhàn)賽的小伙伴說, 闖關(guān)賽有些難度,特別是平行視界功能,之前沒有接觸過,23號時小伙伴也沒有完成闖關(guān)賽,音樂會結(jié)束后我們回到酒店,打開電腦來研究起來,我開始是過了一遍Codelabs的平行視界Sample, 然后按照小伙伴說的,先弄一個電影服務(wù)卡片,然后點(diǎn)擊卡片進(jìn)到電影列表,點(diǎn)擊電影列表某一項,平行視界顯示詳情,在詳情頁可以流轉(zhuǎn). 說到服務(wù)卡片, 我們都知道用JS來寫比較快,要簡單些, 由于我們的目的是要弄懂平行視界, 就直接用了Codelabs里的JS電影卡片,想加上平行視界, 看了N遍平行視界Sample, 修改了多次JS電影卡片,最終還是不能實(shí)現(xiàn)平行視界,當(dāng)時已經(jīng)是零晨3點(diǎn)多了,我和小伙伴說,看來今晚我們搞不定了,會不會是平視視界不支持JS Ability的, 先睡覺了. 第二天到了Codelabs挑戰(zhàn)現(xiàn)場問了一下平行視界支持JS界面嗎? 說不行,目前只支持Java的,無語了. 其實(shí)實(shí)現(xiàn)簡單的平行視界, 也就是兩個配置文件,一行Java代碼都不用寫, 首先配置一下config.json文件, 然后添加easygo.json文件,配置一下左邊顯示哪個Ability, 右邊顯示哪個Ability就可以了,下面來簡單介紹一下開發(fā)過程。
二, 實(shí)現(xiàn)效果
B站視頻:https://www.bilibili.com/video/BV1N34y1Z7Gj/

三, 工程搭建
打開Codelabs網(wǎng)站找到Java電影卡片, 點(diǎn)擊參考到gitee下載這個Sample的源代碼, 上面也說了, 這個實(shí)例是基于Java電影卡片基礎(chǔ)上, 加入平行視界和服務(wù)流轉(zhuǎn)功能, 下載完成后, 解壓出來, 打開DevEco Studio開發(fā)工具, 點(diǎn)擊File -> Open找到剛才解壓出來的MovieCardDemo電影卡片實(shí)例。

四, 新增和修改文件介紹
先說一下項目要簡單支持平行視界, 主要就是兩個配置文件:
1. config.json配置支持平行視界, 在module下添加:
- "metaData": {
 - "customizeData": [
 - {
 - "name": "EasyGoClient",
 - "value": "true"
 - }
 - ]
 - }
 
2. 添加easygo.json文件支持平行視界:
- {
 - "easyGoVersion": "1.0",
 - "client": "com.army.study", // 與config.json文件的bundleName一致
 - "logicEntities": [
 - {
 - "head": {
 - "function": "magicwindow",
 - "required": "true"
 - },
 - "body": {
 - "mode": "1",
 - "abilityPairs": [
 - {
 - "from": "com.huawei.cookbook.MainAbility", // 顯示在平行視界左邊頁面
 - "to": "com.huawei.cookbook.MoviesDetailAbility" // 顯示在平行視界右邊頁面
 - }
 - ],
 - "UX": {
 - "isDraggable": "true",
 - "supportRotationUxCompat": "true",
 - "supportDraggingToFullScreen": "ALL"
 - }
 - }
 - }
 - ]
 - }
 
設(shè)備選擇對話框DeviceDialog是封裝好的一個類, 來自Codelabs平行視界代碼里。
- package com.huawei.cookbook;
 - import com.huawei.cookbook.slice.MoviesDetailAbilitySlice;
 - import ohos.aafwk.ability.continuation.*;
 - import ohos.app.Context;
 - import ohos.hiviewdfx.HiLog;
 - import ohos.hiviewdfx.HiLogLabel;
 - public class DeviceDialog {
 - private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "chuangguan");
 - // context Object
 - private final Context context;
 - // 獲取流轉(zhuǎn)任務(wù)管理服務(wù)管理類
 - private final IContinuationRegisterManager continuationRegisterManager;
 - // Ability token returned after the transfer task management service is registered
 - private int abilityToken;
 - // Device ID returned after a user selects a device in the device list
 - private String selectDeviceId;
 - // 設(shè)置流轉(zhuǎn)任務(wù)管理服務(wù)設(shè)備狀態(tài)變更的回調(diào)
 - private final IContinuationDeviceCallback callback = new IContinuationDeviceCallback() {
 - @Override
 - public void onDeviceConnectDone(String str, String str1) {
 - // Set the device ID after the user selects the device
 - selectDeviceId = str;
 - continuationRegisterManager.updateConnectStatus(abilityToken, selectDeviceId,
 - DeviceConnectState.CONNECTED.getState(), null);
 - returnDeviceId();
 - }
 - @Override
 - public void onDeviceDisconnectDone(String str) {
 - }
 - };
 - // 設(shè)置注冊流轉(zhuǎn)任務(wù)管理服務(wù)回調(diào)
 - private final RequestCallback requestCallback = new RequestCallback() {
 - @Override
 - public void onResult(int result) {
 - abilityToken = result;
 - }
 - };
 - /**
 - * Initialize the DeviceDialog, set the transfer task management service management class,
 - * and register the transfer task management service management class.
 - *
 - * @param continuationRegisterManager continuationRegisterManager
 - * @param slice slice
 - * @since 2021-09-10
 - */
 - public DeviceDialog(IContinuationRegisterManager continuationRegisterManager, Context slice) {
 - this.continuationRegisterManager = continuationRegisterManager;
 - this.context = slice;
 - // 注冊
 - registerManager();
 - }
 - // 注冊流轉(zhuǎn)任務(wù)管理服務(wù)管理類
 - private void registerManager() {
 - // 增加過濾條件
 - ExtraParams params = new ExtraParams();
 - String[] devTypes = new String[]{ExtraParams.DEVICETYPE_SMART_PAD, ExtraParams.DEVICETYPE_SMART_PHONE};
 - params.setDevType(devTypes);
 - continuationRegisterManager.register(context.getBundleName(), params, callback, requestCallback);
 - }
 - /**
 - * 打開設(shè)備選擇框
 - *
 - * @since 2021-09-10
 - */
 - public void showDeviceList() {
 - // 設(shè)置過濾設(shè)備類型
 - ExtraParams params = new ExtraParams();
 - String[] devTypes = new String[]{ExtraParams.DEVICETYPE_SMART_PAD, ExtraParams.DEVICETYPE_SMART_PHONE};
 - params.setDevType(devTypes);
 - // 注冊
 - continuationRegisterManager.register(context.getBundleName(), params, callback, requestCallback);
 - // 顯示選擇設(shè)備列表
 - continuationRegisterManager.showDeviceList(abilityToken, params, null);
 - }
 - // Return the device ID
 - private void returnDeviceId() {
 - HiLog.info(LABEL_LOG, "deviceid::" + selectDeviceId);
 - MoviesDetailAbilitySlice.setDeviceId(selectDeviceId);
 - }
 - /**
 - * 斷開流轉(zhuǎn)任務(wù)管理服務(wù)
 - *
 - * @since 2021-09-10
 - */
 - public void clearRegisterManager() {
 - // 解注冊流轉(zhuǎn)任務(wù)管理服務(wù)
 - continuationRegisterManager.unregister(abilityToken, null);
 - // 斷開流轉(zhuǎn)任務(wù)管理服務(wù)連接
 - continuationRegisterManager.disconnect();
 - }
 - }
 
提示對話框Utils公共類:
- public static void creatToastDialog(Context context, String message) {
 - Component component = LayoutScatter.getInstance(context)
 - .parse(ResourceTable.Layout_layout_toast, null, false);
 - Component componentText = component.findComponentById(ResourceTable.Id_msg_toast);
 - if (componentText instanceof Text) {
 - ((Text) componentText).setText(message);
 - }
 - new ToastDialog(context)
 - .setComponent(component)
 - .setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT)
 - .setAlignment(LayoutAlignment.CENTER).show();
 - }
 
下來說一下關(guān)于服務(wù)流轉(zhuǎn)的代碼, MoviesDetailAbility和MoviesDetailAbilitySlice都實(shí)現(xiàn)IAbilityContinuation接口, 并且實(shí)現(xiàn)接口里的方法:
- public class MoviesDetailAbility extends Ability implements IAbilityContinuation {
 - @Override
 - public void onStart(Intent intent) {
 - super.onStart(intent);
 - super.setMainRoute(MoviesDetailAbilitySlice.class.getName());
 - }
 - @Override
 - public boolean onStartContinuation() {
 - return true;
 - }
 - @Override
 - public boolean onSaveData(IntentParams intentParams) {
 - return true;
 - }
 - @Override
 - public boolean onRestoreData(IntentParams intentParams) {
 - return true;
 - }
 - @Override
 - public void onCompleteContinuation(int i) {
 - }
 - }
 
- public class MoviesDetailAbilitySlice extends AbilitySlice implements IAbilityContinuation {
 - // 此處省略原來的代碼
 - @Override
 - public boolean onStartContinuation() {
 - return true;
 - }
 - @Override
 - public boolean onSaveData(IntentParams saveData) {
 - saveData.setParam("remoteMovieId", movieId);
 - return true;
 - }
 - @Override
 - public boolean onRestoreData(IntentParams restoreData) {
 - this.movieId = Long.parseLong(restoreData.getParam("remoteMovieId").toString());
 - return true;
 - }
 - @Override
 - public void onCompleteContinuation(int i) {
 - isCirculation = false;
 - }
 - }
 
要實(shí)現(xiàn)服務(wù)流轉(zhuǎn), 首先要在config.json權(quán)限申請, module下添加:
- "reqPermissions": [
 - {
 - "name": "ohos.permission.DISTRIBUTED_DATASYNC",
 - "reason": "$string:entry_MoviesDetailAbility",
 - "usedScene":
 - {
 - "ability": [
 - "com.huawei.cookbook.MainAbility",
 - "com.huawei.cookbook.MoviesDetailAbility"
 - ],
 - "when": "always"
 - }
 - },
 - {
 - "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO",
 - "reason": "$string:entry_MoviesDetailAbility",
 - "usedScene":
 - {
 - "ability": [
 - "com.huawei.cookbook.MainAbility",
 - "com.huawei.cookbook.MoviesDetailAbility"
 - ],
 - "when": "always"
 - }
 - }
 - ]
 
同時也在應(yīng)用入口提供顯示權(quán)限申請:
- @Override
 - public void onStart(Intent intent) {
 - super.onStart(intent);
 - super.setMainRoute(MainAbilitySlice.class.getName());
 - // 聲明跨端遷移訪問的權(quán)限
 - requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
 - addActionRoute(ACTION_DETAIL, MoviesDetailAbilitySlice.class.getName());
 - initData();
 - initMyHandler();
 - }
 
到此就介紹完了, 大家是不是感覺到, 我就是一個搬運(yùn)工, 在不同的Sample上, 合并成為一個, 這個Demo確實(shí)是這樣, 把不同的知識點(diǎn)集合在一起, 形成一個符合要求的應(yīng)用, 下來我打算再寫一個一樣需求的應(yīng)用, 但是從創(chuàng)建空白項目開始, 把列表顯示, 詳情, 服務(wù)卡片, 平行視界, 服務(wù)流轉(zhuǎn)體驗出來, 大家有空也一起根據(jù)需求擼出來吧!!! 下面圖片是當(dāng)時HDC2021 Codelabs闖關(guān)賽原圖。
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)


















 
 
 

 
 
 
 