解密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源创计划”,欢迎正在阅读的你也加入,一起分享。

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