Recently (4.12 ~ 4.25), Hongmon OS is holding a developer day, take the opportunity to attend and learn about the current situation and application development experience of Hongmon OS. Developer.huawei.com/consumer/cn…

1. Development environment construction


Download and install the IDE (current version 2.1 Beta3)

Huawei provides an IDE for Harmony app development: DevEco Studio (I don’t like the Eco name, but IT doesn’t matter how PPT is used, can we be practical with development tools?).

You need to log in to Huawei to download the IDE. I installed the Mac version, and the installation process was relatively smooth after downloading

The launch screen shows that DevEco Studio is still a custom IDE based on IntelliJ

Download the SDK

As with Android, the first thing to do when the IDE starts is to download the Harmony SDK

Each version of the SDK provides three sets of apis for developing Java, Js, and C++ code, which need to be consistent across versions. Different huawei devices have different requirements for SDK versions. For example, in the test, it was found that my API4 code could not run on P40, so it was OK to change to API5

About the SDK source code

Note that it is currently not possible to download the source code as a package through SDKManager. The source code needs to be downloaded separately through Gitee

gitee.com/openharmony

This makes it difficult to debug the code, and I wonder if the source code can be packaged with the SDK like Andoird

Create a project

Harmony is a multi-terminal collaboration, so it is very important to diversify the devices, and can create template projects for different devices

Compared to AndroidStudio, Harmony provides a much richer project template. In addition to the UI, the template also provides some data layer code, which is basically a secondary development APP.


2. Hongmeng Project Structure


The IDE interface

Create a template project for News Feature Ability and successfully open it in the IDE:

The Preview window on the right side of Harmony provides a Preview of XML or Ablitiy files, a bit of a Compose Preview feeling, but only static Preview, not interactive

Engineering documents

Project files are similar to Android, and even one-to-one relationships can be found

Harmony Android instructions
entry app The default startup module (main module) is equivalent to app_module
MyApplication XXXApplication Hongmeng’s MyApplication isAbilityPackageA subclass of
MainAbility MainActivity Entry page. Hongmengzhong unified the concept of four components intoAbility
MainAbilityListSlice XXXFragment SliceLike fragments, the basic building block of UI
Component View ComponentThe class is equivalent to View, as described later
config.json AndroidManifest.xml Hongmeng uses JSON instead of XML for Manifest configuration, and the configuration project is similar
resources/base/… res/… All resource files, including Layout files, still use XML
resources/rawfile/ assets/ Rawfile stores raw resources in any format, equivalent to assets
build.gradle build.gradle Compile the script, same thing
build/outpus/… /*.hap build/outputs/… /*.apk Hongmeng’s product ishap(harmony application package)

There’s an.apk file with the same name,

This followed because Hongmeng needed a compatible solution that also supported APK installations

Ability

Ability is an abstraction of what an application is capable of, and Harmony allows applications to be deployed in units of Ability. An application consists of one or more FA (Feature Ability) or PA (Particle Ability). FA has a UI interface to provide the ability to interact with users; While PA has no UI interface, it provides the ability to run tasks in the background and a unified data access abstraction

  • FA supports Page Ability:
    • Page Ability is used to provide the Ability to interact with the user. A Page can be composed of one or more AbilitySlice, AbilitySlice between the Page navigation

  • PA supports Service Ability and Data Ability:
    • Service Ability: Provides the Ability to run tasks in the background.
    • Data Ability: Used to provide a uniform Data access abstraction to the outside world.

There is a sense that Ability can be understood against the four components of Android

Harmony Android
Page Ability (FA) Activity
Service Ability (PA) Service
Data Ability (PA) ContentProvider
AbilitySlice Fragment

The code in

MainAbility

Take the preset News Feature Ability as an example, which is a Page Ability with two slices, registering two slices through the Router

public class MainAbility extends Ability {

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(MainAbilityListSlice.class.getName()); // Add route: ListSlice
        addActionRoute("action.detail", MainAbilityDetailSlice.class.getName());//DetailSlice. }}Copy the code

Here is the page effect of running two slices in the emulator

MainAbilityListSlice MainAbilityDetailSlice

MainAbilityListSlice

Look at the display logic of the list

public class MainAbilityListSlice extends AbilitySlice {...@Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_news_list_layout);
        initView();
        initData(); // Load the data
        initListener();
        newsListContainer.setItemProvider(newsListAdapter); // Set Adatper to View
        newsListAdapter.notifyDataChanged(); // Refresh the data
    }


    private void initListener(a) {
        newsListContainer.setItemClickedListener((listContainer, component, i, l) -> {
            // Route jump "action.detail"
            LogUtil.info(TAG, "onItemClicked is called");
            Intent intent = new Intent();
            Operation operation = new Intent.OperationBuilder()
                    .withBundleName(getBundleName())
                    .withAbilityName("com.example.myapplication.MainAbility")
                    .withAction("action.detail")
                    .build();
            intent.setOperation(operation);
            startAbility(intent);
        });
    }
    
    private void initData(a) {... totalNewsDatas =new ArrayList<>();
        newsDatas = new ArrayList<>();
        initNewsData();/ / fill newsDatas
        newsListAdapter = new NewsListAdapter(newsDatas, this);// Set to Adapter}... }Copy the code

Similar to ListView usage, data is loaded through Adatper; MainAbilityDetailSlice is skipped by route in setItemClickedListener.

The Layout_news_list_layout file is defined as follows. ListContainer, or ListView, is a subclass of Comopnent, and Component is the View in HarmonyOS


      
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:orientation="vertical">

    <ListContainer
        ohos:id="$+id:selector_list"
        ohos:height="40vp"
        ohos:width="match_parent"
        ohos:orientation="horizontal"
        />

    <Component
        ohos:height="0.5 the vp"
        ohos:width="match_parent"
        ohos:background_element="#EAEAEC"
        />

    <ListContainer
        ohos:id="$+id:news_container"
        ohos:height="match_parent"
        ohos:width="match_parent"/>


</DirectionalLayout>
Copy the code

Take a look at the Adapter implementation, which inherits from BaseItemProvider

/** * News list adapter */
public class NewsListAdapter extends BaseItemProvider {
    private List<NewsInfo> newsInfoList;
    private Context context;

    public NewsListAdapter(List<NewsInfo> listBasicInfo, Context context) {
        this.newsInfoList = listBasicInfo;
        this.context = context;
    }

    @Override
    public int getCount(a) {
        return newsInfoList == null ? 0 : newsInfoList.size();
    }

    @Override
    public Object getItem(int position) {
        return Optional.of(this.newsInfoList.get(position));
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public Component getComponent(int position, Component componentP, ComponentContainer componentContainer) {
        ViewHolder viewHolder = null;
        Component component = componentP;
        if (component == null) {
            component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_news_layout, null.false);
            viewHolder = new ViewHolder();
            Component componentTitle = component.findComponentById(ResourceTable.Id_item_news_title);
            Component componentImage = component.findComponentById(ResourceTable.Id_item_news_image);
            if (componentTitle instanceof Text) {
                viewHolder.title = (Text) componentTitle;
            }
            if (componentImage instanceof Image) {
                viewHolder.image = (Image) componentImage;
            }
            component.setTag(viewHolder);
        } else {
            if (component.getTag() instanceofViewHolder) { viewHolder = (ViewHolder) component.getTag(); }}if (null! = viewHolder) { viewHolder.title.setText(newsInfoList.get(position).getTitle()); viewHolder.image.setScaleMode(Image.ScaleMode.STRETCH); }return component;
    }

    /** * ViewHolder which has title and image */
    private static class ViewHolder { Text title; Image image; }}Copy the code

It’s basically a standard ListAdatper, replacing a View with a Component.

About the Simulator

The code is ready to run in the emulator. A few things to say about the simulator:

  1. Harmony’s emulator starts very quickly, without the need to download an image, because the emulator doesn’t run locally, it’s just VNC from a remote device, so it has to be used online, and it loses frames when it’s not smooth enough. Not everyone can afford a P40, though the real thing works better

  2. The simulator is embedded in an IDE window (like the Preview window), which is not independent of the window, which causes the problem that when multiple ides are open at the same time, the simulator may be displayed in another IDE (like Logcat off-track).

  3. To use the emulator, you have to go through itDeveloper certification, the official recommendation to use bank card authentication. The emulator is connected remotely to a real device, is there a charge for renting the device for the future?Remember to read an article before, if it is from a foreign registered account can use the simulator without authentication, but too lazy to toss about


3. Develop JS applications


In addition to Java, Hongmeng also supports jS-BASED application development and improves its cross-platform capabilities with front-end technology.

Hongmon provides a variety of commonly used UI components for JS project, but it does not use the current mainstream JS components like React and Vue, and is still based on the traditional way of CSS3/HTML5/JS development. The JS engineering structure is as follows

directory instructions
common This option is used to store common resource files, such as media resources, custom components, and JS documents
i18n This parameter is optional. It is used to store json files in multiple languages
pages/index/index.hml The HML file defines the layout structure of the page, the components used, and the hierarchy of those components
pages/index/index.css The CSS file defines the style and layout of the page, including style selectors and various style properties
pages/index/index.js This file defines all the logical relationships used in the page, such as data, events, and so on
resources This option is used to store resource configuration files, such as global style and multi-resolution load configuration files
app.js Global JavaScript logic file and application lifecycle management.


4. Migrate across devices


It may feel like Android, but the best feature of HarmonyOS is its ability to collaborate across devices, such as the ability to move pages seamlessly between devices within the same user.

For example, to migrate Page from device A to device B, perform the following steps:

  • Page on device A requests migration.
  • HarmonyOS calls back to the save data method of the Page on device A to save the data necessary for the migration.
  • HarmonyOS starts the same Page on device B and calls back its recovery method.

The migration is requested by calling continueAbility(). Obtain the device list as follows, and request migration after successful pairing

doConnectImg.setClickedListener( 
	clickedView -> { 
		// Get the list of online devices with the FLAG_GET_ONLINE_DEVICE flag
		List deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
		if (deviceInfoList.size() < 1) { 
			WidgetHelper.showTips(this."No network equipment"); 
		} else { 
			DeviceSelectDialog dialog = new DeviceSelectDialog(this); 
			// Click to migrate to the specified device
			dialog.setListener( 
				deviceInfo -> { 
					LogUtil.debug(TAG, deviceInfo.getDeviceName()); 
					LogUtil.info(TAG, "continue button click"); 
					try { 
						// Start task migration
						continueAbility(); 
						LogUtil.info(TAG, "continue button click end"); 
					} catch (IllegalStateException | UnsupportedOperationException e) { 
						WidgetHelper.showTips(this, ResourceTable.String_tips_mail_continue_failed); } dialog.hide(); }); dialog.show(); }});Copy the code

Page migration involves data transfer, which requires communication with an IAbilityContinuation.

IAbilityContinuation for communication across devices

Pages migrating across devices need to implement the IAbilityContinuation interface.

Note: An application may contain multiple pages. You only need to implement the IAbilityContinuation interface in pages that support migration by using the following method. At the same time, this Page contains all AbilitySlice also need to implement this interface.

public class MainAbility extends Ability implements IAbilityContinuation {...@Override 
    public void onCompleteContinuation(int code) {} 
 
    @Override 
    public boolean onRestoreData(IntentParams params) { 
        return true; 
    } 
 
    @Override 
    public boolean onSaveData(IntentParams params) { 
        return true; 
    } 
 
    @Override 
    public boolean onStartContinuation(a) { 
        return true; }}public class MailEditSlice extends AbilitySlice implements IAbilityContinuation {...@Override 
    public boolean onStartContinuation(a) { 
        LogUtil.info(TAG, "is start continue"); 
        return true; 
    } 
 
    @Override 
    public boolean onSaveData(IntentParams params) {... LogUtil.info(TAG,"begin onSaveData:"+ mailData); . LogUtil.info(TAG,"end onSaveData"); 
        return true; 
    } 
 
    @Override 
    public boolean onRestoreData(IntentParams params) { 
        LogUtil.info(TAG, "begin onRestoreData"); . LogUtil.info(TAG,"end onRestoreData, mail data: " + cachedMailData); 
        return true; 
    } 
 
    @Override 
    public void onCompleteContinuation(int i) { 
        LogUtil.info(TAG, "onCompleteContinuation"); terminateAbility(); }}Copy the code
  • OnStartContinuation (): After a Page requests a migration, the system first calls back to this method, where the developer can decide whether the migration is currently possible, for example, a pop-up that lets the user confirm whether to start the migration.

  • OnSaveData (): If onStartContinuation() returns true, the system calls back to this method, and in this callback the developer saves data that must be passed to another device to restore the Page state.

  • OnRestoreData (): After the Page has finished saving data on the source device, the system calls back this method on the target device, and the developer receives the data used to restore the Page state in this callback. Note that a Page on the target device restarts its life cycle regardless of how its boot mode is configured. The system calls back to this method before onStart().

  • OnCompleteContinuation (): Once the recovery on the target device is complete, the system calls back this method on the Page on the source device to notify the application that the migration process has ended. This is where the developer can check whether the migration was successful and handle the actions of the end of the migration. For example, the application can terminate its life cycle after the migration is complete.

Take Page migration from device A to device B as an example. The detailed process is as follows:

  1. Page on device A requests migration.
  2. The system calls back Page on device A and all AbilitySlice instances in the AbilitySlice stackIAbilityContinuation.onStartContinuation()Method to verify whether the migration is currently available immediately.
  3. If the migration is possible immediately, the system calls back all AbilitySlice instances of Page on device A and its AbilitySlice stackIAbilityContinuation.onSaveData()Method to save the data necessary to restore state after migration.
  4. If the data is saved successfully, the system starts the same Page on device B, restores the AbilitySlice stack, and then calls backIAbilityContinuation.onRestoreData()Method to pass previously saved data; After device B on this Page fromonStart()Begins its lifecycle callback.
  5. The system calls back Page on device A and all AbilitySlice instances in the AbilitySlice stackIAbilityContinuation.onCompleteContinuation()Method to notify the data recovery success.


5. Summary and impressions


  1. From the SDK to the IDE, it is highly similar to Android, and any Android developer is basically a quasi-developer
  2. While AndroidStudio is iterating quickly, DevEco Studio still has a significant gap in functionality
  3. You need to authenticate your real name before you can use the full functionality of the IDE
  4. The source code requires a separate download and is not debug friendly
  5. Kotlin is not currently supported. The trend is there, so it will be supported in the future, and the fact that Kotlin is open source is not a problem
  6. The technical architecture of the JS UI framework is also somewhat outdated
  7. The killer card is support for multi-end collaboration, but it may take more vendors to really take off

At present, people’s attitudes towards Hongmeng are polarized. Some people adore hongmeng while others devalue it. In my opinion, it is unnecessary to give hongmeng more space and patience, watch its change and enjoy its success. Of course, the first choice needs Huawei to do not take the initiative to hype, really calm down to polish Hongmeng, as long as Huawei is determined and patient, as developers why don’t we support it?

Harmony Online Challenge

Along with the developer activity day, Hongmeng also held several rounds of online challenge activities (still in progress), the difficulty is not high participation can be completed, and the winning rate is high (personal testing), interested can participate, I hope I pass the good luck to you

Event details: mp.weixin.qq.com/s/3IrZGZkm1…

A link to the

  • HarmonyOS official www.harmonyos.com/cn/home
  • HarmonyOS developer documentation developer.harmonyos.com/cn/document…
  • HarmonyOS source gitee.com/openharmony