解密HarmonyOS核心優勢——分佈式開發

HarmonyOS到底跟Android有什麼不同呢?HarmonyOS最大的不同點在於它是爲萬物互聯而生的,而不僅僅是爲了手機而生,最核心優勢就是它的分佈式開發。那麼到底什麼是分佈式?它有什麼不可替代的價值?它又如何開發呢?小編將在本篇爲大家一一解密。

首先來看HarmonyOS官網一個案例圖吧,這個案例講的是一個用戶用手機打車軟件叫了網約車,然後把手機裝兜裏,擡手在手錶上可以看車輛應答進展,手機與手錶之間的信息是無縫切換的,如同一個設備兩個屏幕一樣,這就是分佈式的最好體現。所以通俗來講,所謂分佈式,就是在不同設備之間實時協同工作,如同一個大設備不同模塊一樣能緊密配合。這種跨設備協同能力,與傳統的android系統不一樣,傳統android設備之間需要多個app約定好協議才能搜索、發現、配對後聯機工作。而HarmonyOS是直接在系統層支持了多設備間的發現、連接,對應用來說只用調用簡單的接口,就可以實現分佈式運行在多個設備上進行高效協同。未來科幻電影裏的智能家居場景,就需要HarmonyOS這樣的操作系統才能支撐,這也是HarmonyOS能夠彎道超車安卓的一大潛在機遇。

手機手錶協同叫車

好,說了HarmonyOS分佈式的含義和價值後,我們直接上代碼,帶領大家來體驗一下如何開發分佈式應用吧。在New Project時,選擇News Feature Ability這個模板,這個模板是一個新聞信息流頁面,包含一個新聞列表頁和一個新聞詳情頁。這個demo的Ability如何佈局、列表List如何用MVC實現等等,這裏就不詳細說了。我們直接找到最核心的分佈式代碼。

創建demo工程

第一步,先看看config.json文件,這個文件跟android裏的mainfest.xml一樣,是定義一些ability屬性及所需權限的,這裏面有三個非常重要的權限,它表示是否允許本app訪問和監聽其它分佈式設備。

{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
},
{
"name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
},
{
"name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
},

第二步,分佈式嘛,肯定是要一個設備連接訪問另一個設備,在HarmonyOS裏,我們可以把本機叫做客戶端,把要連接的目標設備叫服務端,那麼客戶端與服務端是兩個獨立的進程,如何通信呢?HarmonyOS採用了流行的proxy/stub模式,即代理存根模式。通過IDL(接口定義語言)定義設備間通信的接口,然後用工具自動生成對應的proxy和stub文件,其中proxy運行在客戶端,stub運行在服務端,他們像是中介一樣,連接着客戶端和服務端。

代理和存根

代理框架圖

我們從上面截圖裏可以看到,IDL裏只有一個接口,就是transShare(),它有5個參數,從變量名稱我們大概可以猜到其含義是設備ID、新聞網址、新聞標題、新聞摘要、新聞封面圖。這個IDL接口的目的是可以讓客戶端設備把一條新聞信息同步給服務端設備。

void tranShare(
String deviceId,
String shareUrl,
String shareTitle,
String shareAbstract,
String shareImg)

我們再看一下根據這個IDL文件自動生成的proxy/stub文件代碼,以proxy爲例,我們可以看到它主要是把新聞各個信息字段通過data.write()函數序列化,然後把序列化的結果通過remote.sendRequest()方法發給服務端,服務端那邊會通過stub文件接收這個對象,然後再把它反序列化,從而得到新聞各個信息字段。stub代碼這裏就不貼出來了。

package com.example.myapplication.manager;

import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;

/**
* News demo
*/

public class NewsDemoIDLProxy implements INewsDemoIDL {
private static final String DESCRIPTOR = "com.example.myapplication.INewsDemoIDL";

private static final int COMMAND_TRAN_SHARE = IRemoteObject.MIN_TRANSACTION_ID;

private final IRemoteObject remote;

NewsDemoIDLProxy(IRemoteObject remote) {
this.remote = remote;
}

@Override
public IRemoteObject asObject() {
return remote;
}

@Override
public void tranShare(
String deviceId,
String shareUrl,
String shareTitle,
String shareAbstract,
String shareImg) throws RemoteException {
MessageParcel data = MessageParcel.obtain();
MessageParcel reply = MessageParcel.obtain();
MessageOption option = new MessageOption(MessageOption.TF_SYNC);

data.writeInterfaceToken(DESCRIPTOR);
data.writeString(deviceId);
data.writeString(shareUrl);
data.writeString(shareTitle);
data.writeString(shareAbstract);
data.writeString(shareImg);

try {
remote.sendRequest(COMMAND_TRAN_SHARE, data, reply, option);
reply.readException();
} finally {
data.reclaim();
reply.reclaim();
}
}
}

定義好了代理和存根之後,客戶端設備就可以通過代理連接服務端了。那麼客戶端又該如何發現和選中服務端設備呢?我們先運行一下demo看看界面,首頁是一個新聞列表頁,點擊某條新聞後,是一個新聞詳情頁面,底部右側角上有個分享按鈕,點了後會彈出一個對話框(Harmony devices),這個對話框本意是要顯示發現的其他HarmonyOS設備,以便將新聞信息分佈式的同步到那些設備上。由於小編這裏調試使用的是遠程雲手機,因此沒有辦法真正發現其他HarmonyOS設備,如果是在家裏用真正的手機調試,旁邊又有其他HarmonyOS設備比如電視的話,那這個對話框裏就會顯示HarmonyOS設備列表的。

新聞列表界面

新聞詳情頁

點分享按鈕彈出的對話框

那到底要怎麼發現和連接分佈式設備呢?在新聞詳情頁代碼裏(MainAbilityDetailSlice.java)裏,我們可以看到分享按鈕的響應事件處理代碼,它調用了兩個函數,一個用來獲取分佈式設備信息,一個用來展示設備列表。

iconShared.setClickedListener(listener -> {
initDevices();
showDeviceList();
});

再看看initDevices()是如何做的?通過HarmonyOS提供的設備管理API DeviceManager直接可以獲取分佈式設備信息,這裏返回的是一個List,因爲可連接的分佈式設備可能有多個。

private void initDevices() {
if (devices.size() > 0) {
devices.clear();
}
List<ohos.distributedschedule.interwork.DeviceInfo> deviceInfos =
DeviceManager.getDeviceList(ohos.distributedschedule.interwork.DeviceInfo.FLAG_GET_ONLINE_DEVICE);
LogUtil.info("MainAbilityDetailSlice", "deviceInfos size is :" + deviceInfos.size());
devices.addAll(deviceInfos);
}

然後再把這些設備顯示出來,讓用戶選擇需要同步到哪個設備上去分佈式運行?這裏就比較簡單了,把設備List綁定到一個對話框的列表UI裏即可。

private void showDeviceList() {
dialog = new CommonDialog(MainAbilityDetailSlice.this);
dialog.setAutoClosable(true);
dialog.setTitleText("Harmony devices");
dialog.setSize(DIALOG_SIZE_WIDTH, DIALOG_SIZE_HEIGHT);
ListContainer devicesListContainer = new ListContainer(getContext());
DevicesListAdapter devicesListAdapter = new DevicesListAdapter(devices, this);
devicesListContainer.setItemProvider(devicesListAdapter);
devicesListContainer.setItemClickedListener((listContainer, component, position, listener) -> {
dialog.destroy();
startAbilityFA(devices.get(position).getDeviceId());
});
devicesListAdapter.notifyDataChanged();
dialog.setContentCustomComponent(devicesListContainer);
dialog.show();
}

仔細看看上面代碼中,設備列表的點擊事件listener,它調用了startAbilityFA()函數,意圖在於當用戶選擇某個設備時,就開始分佈式遷移到對應設備上去運行。打開它的代碼,可以看到第一步是定義一個intent,裏面填入目標設備deviceID,目標設備裏要運行的ability(這個案例裏是一個服務SharedService)。然後開始調用 connectAbility()函數連接遠程設備,在連接成功的回調函數裏,就可以拿到遠端設備的代理,通過IDL接口就可以像操控本地設備一樣,操控遠端設備。至此,我們就完成了分佈式開發啦。

private void startAbilityFA(String devicesId) {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId(devicesId)
.withBundleName(getBundleName())
.withAbilityName("com.example.myapplication.SharedService")
.withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
.build();
intent.setOperation(operation);
boolean connectFlag = connectAbility(intent, new IAbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {
INewsDemoIDL sharedManager = NewsDemoIDLStub.asInterface(iRemoteObject);
try {
sharedManager.tranShare(devicesId, "url", "title", "abstract", "image");
} catch (RemoteException e) {
LogUtil.info("MainAbilityDetailSlice", "connect successful,but have remote exception");
}
}

@Override
public void onAbilityDisconnectDone(ElementName elementName, int i) {
disconnectAbility(this);
}
});
if (connectFlag) {
DialogUtil.toast(this, connectFlag ? "Sharing succeeded!"
: "Sharing failed. Please try again later.", WAIT_TIME);
}
}

作爲Android開發者,看完HarmonyOS核心優勢分佈式代碼後,我們反過來從安卓裏去找類似設計,可以看到與安卓Activity去Bind它的Services邏輯有點像,都是通過connect回調進行操作。但安卓的bind機制只是爲了完成跨進程通信,而HarmonyOS的分佈式機制是爲了完成跨設備通信。這一點是HarmonyOS勝於安卓之處,HarmonyOS這樣設計,會讓所有的設備都能虛擬爲一個大終端,每個設備都可以成爲其他設備的一個組件,從而實現軟件定義硬件。HarmonyOS的核心優勢現在你明白了嗎?

來源:

https://www.toutiao.com/i6927593749321171468/

作者 | 新科技觀察員

本文觀點不代表我方觀點






end






往 期 精 選 文 章 回 顧


達標率超50%,2021年首份綠標評測報告出爐


攜手華爲引領摺疊屏生態,HUAWEI Mate X2震撼登場


牽引行業健康發展,《智能音箱語音交互測試標準》發佈


本文分享自微信公衆號 - 軟件綠色聯盟(sgachina)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章