Mobile Development 11 min read

How to Build Distributed Apps on HarmonyOS: A Step‑by‑Step Guide

This article explains the core concepts of HarmonyOS distributed development, compares it with Android, and walks through a complete example—including permission configuration, IDL definition, proxy‑stub generation, device discovery, UI handling, and remote invocation—so developers can create cross‑device applications.

21CTO
21CTO
21CTO
How to Build Distributed Apps on HarmonyOS: A Step‑by‑Step Guide

HarmonyOS differs from Android in that it is designed for the Internet of Things, supporting distributed development across multiple devices rather than just phones. Its key advantage is a system‑level distributed framework that enables seamless collaboration between devices such as phones, watches, and TVs.

For example, a user can order a ride on a phone, then view the vehicle’s status on a smartwatch; the phone and watch share data in real time as if they were two screens of a single device. Unlike Android, which requires apps to negotiate protocols before devices can communicate, HarmonyOS provides built‑in discovery and connection APIs, allowing developers to call simple interfaces for distributed execution.

Project Setup and Permissions

When creating a new project, select the News Feature Ability template. The config.json file defines ability attributes and required permissions, including:

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

IDL and Proxy/Stub Generation

An IDL file defines the remote interface. In this demo it contains a single method tranShare() with five parameters (deviceId, shareUrl, shareTitle, shareAbstract, shareImg) used to synchronize a news item to another device.

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

The build tool generates proxy and stub classes. The proxy serializes the parameters with MessageParcel.writeString() and sends the request via remote.sendRequest(). The stub receives the parcel, deserializes it, and processes the data on the server side.

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();
    }
}

Device Discovery and UI

Using DeviceManager.getDeviceList(), the app obtains a list of online distributed devices. The list is displayed in a dialog titled “Harmony devices”. When the user selects a device, the app calls startAbilityFA() to launch the remote ability.

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);
}
private void showDeviceList() {
    dialog = new CommonDialog(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();
}

Connecting to the Remote Ability

The startAbilityFA() method builds an Intent with the target device ID, bundle name, and ability name, then calls connectAbility(). Upon a successful connection, the proxy object invokes tranShare() on the remote side.

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, "Sharing succeeded!", WAIT_TIME);
    }
}

Comparison with Android

Android’s bind‑service mechanism only supports inter‑process communication on a single device, whereas HarmonyOS’s distributed framework enables cross‑device communication, allowing a group of devices to behave as a single logical terminal. This design gives HarmonyOS a distinct advantage for IoT scenarios.

Understanding these mechanisms lets Android developers leverage HarmonyOS to create truly distributed applications that run seamlessly across phones, wearables, TVs, and other smart devices.

Phone‑watch collaboration
Phone‑watch collaboration
Proxy‑stub diagram
Proxy‑stub diagram
Proxy framework
Proxy framework
News list UI
News list UI
News detail UI
News detail UI
Share dialog
Share dialog
HarmonyOScross-deviceIDLDistributed DevelopmentProxy-Stub
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.