鸿蒙HarmonyOS到底跟android有什么不同呢?
鸿蒙最大的不同点在于它是为万物互联而出生的,而不仅仅是为了手机而生,最核心优势就是它的分布式开发。那么到底什么是鸿蒙分布式?它有什么不可替代的价值?它又如何开发呢?小编将在本篇为大家一一解密。
首先来看鸿蒙官网一个案例图吧,这个案例讲的是一个用户用手机打车软件叫了网约车,然后把手机装兜里,抬手在手表上可以看车辆应答进展,手机与手表之间的信息是无缝切换的,如同一个设备两个屏幕一样,这就是分布式的最好体现。所以通俗来讲,所谓分布式,就是在不同设备之间实时协同工作,如同一个大设备不同模块一样能紧密配合。这种跨设备协同能力,与传统的android系统不一样,传统android设备之间需要多个app约定好协议才能搜索、发现、配对后联机工作。而harmonyos是直接在系统层支持了多设备间的发现、连接,对应用来说只用调用简单的接口,就可以实现分布式运行在多个设备上进行高效协同。未来科幻电影里的智能家居场景,就需要鸿蒙这样的操作系统才能支撑,这也是鸿蒙能够弯道超车安卓的一大潜在机遇。
手机手表协同叫车
好,说了鸿蒙分布式的含义和价值后,我们直接上代码,带领大家来体验一下如何开发分布式应用吧。在New Project时,选择News Feature Ability这个模板,这个模板是一个新闻信息流页面,包含一个新闻列表页和一个新闻详情页。这个demo的Ability如何布局、列表List如何用MVC实现等等,由于在上篇电商demo里已经解析过,这里就不详细说了。我们直接找到最核心的分布式代码。
创建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"
},
第二步,分布式嘛,肯定是要一个设备连接访问另一个设备,在鸿蒙里,我们可以把本机叫做客户端,把要连接的目标设备叫服务端,那么客户端与服务端是两个独立的进程,如何通信呢?鸿蒙采用了流行的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),这个对话框本意是要显示发现的其他鸿蒙设备,以便将新闻信息分布式的同步到那些设备上。
由于小编这里调试使用的是远程云手机,因此没有办法真正发现其他鸿蒙设备,如果是在家里用真正的手机调试,旁边又有其他鸿蒙设备比如电视的话,那这个对话框里就会显示鸿蒙设备列表的。
新闻列表界面
新闻详情页
点分享按钮弹出的对话框
那到底要怎么发现和连接分布式设备呢?在新闻详情页代码里(MainAbilityDetailSlice.java)里,我们可以看到分享按钮的响应事件处理代码,它调用了两个函数,一个用来获取分布式设备信息,一个用来展示设备列表。
iconShared.setClickedListener(listener -> {
initDevices();
showDeviceList();
});
再看看initDevices()是如何做的?通过鸿蒙系统提供的设备管理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开发者,看完鸿蒙核心优势分布式代码后,我们反过来从安卓里去找类似设计,可以看到与安卓Activity去Bind它的Services逻辑有点像,都是通过connect回调进行操作。
但安卓的bind机制只是为了完成跨进程通信,而鸿蒙的分布式机制是为了完成跨设备通信。这一点是鸿蒙胜于安卓之处,鸿蒙这样设计,会让所有的设备都能虚拟为一个大终端,每个设备都可以成为其他设备的一个组件,从而实现软件定义硬件。鸿蒙的核心优势现在你明白了吗?
作者:大岳岳
相关阅读:
中国芯片之父张汝京:创立世界第三大芯片生产厂,成功为华为“续命 ”
浅析鸿蒙系统 JavaScript GUI 技术栈
鸿蒙或成第五大操作系统,超越Linux
关于21CTO
21CTO.com是中国互联网第一技术社交与学习平台。为CTO、技术总监,技术专家,架构师、技术经理,高级研发工程师、PM等提供学习成长,教育培训,工作机会、人脉影响力等产品,同时为企业提供人才招聘,企业培训,软件研发等服务。
发表评论 取消回复