Teach you how to develop the first HarmonyOS (Hongmeng) mobile application

1. Introduction to mobile application development

Mobile App Development:

  • Android
  • IOS
  • HarmonyOS (Hongmeng)

2. Introduction to HarmonyOS

Documentation Overview-HarmonyOS Application Development Official Website

2.1 Definition of the system

2.1.1 Positioning of the system

HarmonyOS has three major features:

  • The devices equipped with this operating system are integrated at the system level to form a super terminal, so that the hardware capabilities of the devices can be expanded elastically, and hardware mutual assistance and resource sharing between devices can be realized. For consumers, HarmonyOS can integrate the capabilities of various terminals in life scenarios, realize fast connection, mutual assistance, and resource sharing between different terminal devices, match appropriate devices, and provide smooth full-scenario experience.
  • For developers, realize one-time development and multi-terminal deployment. For application developers, HarmonyOS uses a variety of distributed technologies to make application development independent of the differences in the form of different terminal devices, so that developers can focus on upper-level business logic and develop application more conveniently and efficiently. use.
  • A set of operating systems can meet the needs of devices with different capabilities, achieving a unified OS and flexible deployment. For device developers, HarmonyOS adopts a component-based design solution, which can be flexibly tailored according to the resource capabilities and business characteristics of the device to meet the operating system requirements of different types of terminal devices.

2.1.2 System Architecture

  • Kernel layer: Provides the basic capabilities of the mobile operating system. HarmonyOS adopts a multi-core system design, based on the Linux kernel and LiteOS, using the Linux microkernel (using the simplest functions of Linux)
    • Linux kernel: the kernel of the mobile operating system
    • LiteOS kernel: the kernel of intelligent hardware
  • System service layer: HarmonyOS core capability collection, these capabilities are determined by the system itself, and provide service call functions for our application development. The capabilities provided by the system service layer can be called by the applications we develop.
  • Framework layer: Provides interfaces for calling programs in different languages ​​for HarmonyOS application development

2.2 The development history of Hongmeng

2.2.1 "Hongmeng"

Pangu opened up the world - a piece of chaos (Hongmeng era) determined to break the ground on the road of localization of mobile phone systems

2.2.2 Development History

  • In 2012, Huawei began planning the smart operating system "Hongmeng"
  • In May 2019, Huawei applied for the "Hongmeng" trademark
  • On May 17, 2019, Hongmeng system was released
  • In August 2019, the official version of Hongmeng was released, implementing open source
  • September 2020, Hongmeng 2.0 (beta)
  • On the evening of June 2, 2021, Huawei released HarmonyOS 2.0 online --- mobile phones

2.3 Differences between Hongmeng and Android

2.3.1 Kernel

  • Android: Based on the Linux kernel design, it relies heavily on Linux (that is to say, most functions of the Android operating system depend on Linux)
  • Hongmeng: adopts multi-core design, Linux kernel + LiteOS kernel, and the operating system minimally relies on the Linux kernel

2.3.2 Operating Efficiency

  • Android: The operation of the application is based on the virtual machine (Java---JDK compiler---bytecode---virtual machine---operating system)

  • Hongmeng: Fangzi Compiler (Java----Fangzi Compiler---Machine Code---Operating System)

It is said that the operating efficiency of Hongmeng system is 50%+ higher than that of Android

2.4 Technical Features and System Security

2.4.1 Technical characteristics

  • Hardware mutual assistance, resource sharing
  • One-time development, multi-terminal deployment
  • Unified OS, flexible deployment

2.4.2 System Security

  • The Right Person: Efficient and Secure User Identification
  • The correct device: identification of the device
  • Correct use of data: data security

3. The first Hongmeng app

3.1 Development preparation

3.1.1 Development Environment Construction (Java)

  • Install JDK, configure environment variables
  • Download and install DevEco Studio integrated development environment (an IDE based on Idea development dedicated to Hongmeng application development)

download link

Huawei Operating System DevEco Studio and SDK Download and Upgrade | HarmonyOS Developer

Install

  • Run the installation package
  • Click Next
  • Select the installation directory
  • Create a desktop shortcut
  • start installation

Run DevEco Studio

When starting the development environment for the first time, it will download the SDK required by Hongmeng development
  • Double-click the desktop shortcut to open DevEco Studio
  • get started
  • Select the SDK directory
  • Click Next to go to the next step
  • Select Accept and click Next to start downloading the SDK
  • Click Finish to complete the download and start using

3.1.2 Registering a HUAWEI ID

Register_HUAWEI ID (huawei.com)

3.2 Create Hongmeng App

3.3 Hongmeng application directory structure

3.4 Run the project

3.4.1 Start Harmony Simulator

  • Tools—Device Manager
  • Click the Login button in the pop-up window to log in with your HUAWEI ID
  • Start an emulator

3.5 The startup process of Hongmeng App

3.5.1 config.json

config.json is the main configuration file of Hongmeng App

  • app configuration: define the unique identifier of the current application
    • The unique identifier of the bundleName application (the general package name is the company name + application name)
    • version The version of the application
  • module configuration: used to declare the information of the current application (package, main class, main interface, function module declaration, adapted device type, etc.)
    • mainAbility declares the Ability loaded by default when the current application starts

    • deviceType declares the device type that the current application is adapted to

    • abilities declare the configuration information of each ability in the current application

      • Create an ability, then the configuration information of the corresponding ability will be automatically generated in config.json.

3.5.2 Application startup process

  • Start the Hongmeng app to load the config.json file, and load  mainAbility the main interface of the startup app according to the configuration

    "mainAbility": "com.example.myapplication.demo01.MainAbility"
  • Execute the onStart method of MainAbility

    MainAbility is a container for displaying the interface. In onStartthe method, the view interface displayed in the current interface container is specified by calling the setMainRoute method

    // ability is equivalent to a container (or browser window), 
    // displayed in the container by filling a view slice (body in html). 
    // MainAbilitySlice is an interface 
    super.setMainRoute(MainAbilitySlice.class.getName());
  • Execute  onStart the rendering of the completed interface in MainAbilitySlice

    A slice is an interface. What views are displayed in the interface are loaded and rendered through the onstart method

3.5.3 Hello, where did you come from in the world?

$string: Indicates a sing for the reference, which means to search for the key-value pair in the string file, as shown in the figure, the key is: the value of maintainability_HelloWorld.

4. Ability Framework

4.1 Introduction to Ability

Ability is an abstraction of the capabilities of the application, and it is also an important part of the application. An application can have multiple capabilities

(that is, it can contain multiple abilities), and HarmonyOS supports the deployment of applications in units of abilities.

Ability can be divided into  FA(Feature Ability) and PA (Particle Ability) two types, each type is

Developers provide different templates to achieve different business functions.

  • FA⽀持Page Ability:

    Page template is the only template supported by FA, ​​which is used to provide the ability to interact with users. A Page instance can contain a

    Group related pages, each page is represented by an AbilitySlice instance.

    ​ 

  • PA supports Service Ability and Data Ability:

    • Service template: used to provide the ability to run tasks in the background.
    • Data template: used to provide a unified data access abstraction to the outside world.

4.2 PageAbility

4.2.1 Introduction to PageAbility

A PageAbility is equivalent to a page container (browser window), and an AbilitySlice is equivalent to displaying in the container

A page in (HTML)

Page template (hereinafter referred to as "Page") is the only template supported by FA, ​​which is used to provide the ability to interact with users. A Page can be composed of one or more AbilitySlices. AbilitySlice refers to the sum of a single page of the application and its control logic (equivalent to an HTML file). Multiple Slices can be included in one Abiliy

商品管理: 	ProductAbility(PageAbility):
 goods-list.html	ProductListSlice
 goods-detail.html 	ProductDetailSlice

4.2.2 Creating AbilitySlices

  • AbilitySlice creates a slice package

  • Create steps:

    • Create a class that inherits the ohos.aafwk.ability.AbilitySlice class

      public class MainAbilitySlice2 extends AbilitySlice {
      
      }
    • resources/base/layout Create layout files in the directory 

      <?xml version="1.0" encoding="utf-8"?>
      <DirectionalLayout
       xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:height="match_parent"
       ohos:width="match_parent"
       ohos:orientation="vertical">
       <Text
       ohos:height="match_content"
       ohos:width="match_content"
       ohos:text="这是测试⽂本"
       ohos:text_color="#ff0000"
       ohos:text_size="40vp"></Text>
      </DirectionalLayout> 
    • Override the onStart method in the created AbilitySlice class, and call the setUIContent method to load the layout file

      Load resources under the resources directory through ResourceTable

      public class MainAbilitySlice2 extends AbilitySlice { 
          @Override 
          protected void onStart(Intent intent) { 
              super.onStart(intent); 
       		//Define the slice view component (Java, XML) 
       		//setUIContent(int); Load the layout file of the application (xml ) as the view of the current slice 
       		setUIContent(ResourceTable.Layout_ability_main_slice2); 
      	} 
      }

4.2.3 PageAbility life cycle

A Page can contain multiple Slices, but only one slice can be displayed at the same time, how to set the default PageAbility

Displayed slices?

Multiple life cycle methods are provided in a Page Ability, and these methods are different in the current PageAbility loaded

stage will automatically call

illustrate

The INACTIVE state is a short-lived state, which can be understood as "active".

public class MainAbility extends Ability { 
     /** 
      * When the system creates the current PageAbility instance for the first time, it will automatically call the onstart method. That is to say, for a Page, the onStart method will only be executed once 
      */ 
     public void onStart(Intent intent) { 
     	super.onStart(intent); 
     	super.setMainRoute(MainAbilitySlice2.class.getName()); 
     	System .out.println("--------------onStart"); 
     } 
    
     /** 
      * When the current Page enters the active state and enters the foreground of the mobile phone to get the focus, the onActive method will be triggered Execution of 
      */ 
     protected void onActive() { 
     	super.onActive(); 
     	System.out.println("--------------onActive"); 
 	} 
    
     /** 
      * The current PageAbility is lost Focus (the page switches to the background, switches to other Pages), triggers the execution of the onInactive method 
      */
     protected void onInactive() { 
     	super.onInactive(); 
     	System.out.println("--------------onInactive"); 
     } 
    
     /** 
      * The current PageAbility is switched to the background, invisible When onBackground is triggered 
      */ 
     protected void onBackground() { 
     	super.onBackground(); 
     	System.out.println("--------------onBackground"); 
     } 
     /** 
      * Trigger onForeground execution when PageAbility switches from the background invisible state (the page is in the background but not destroyed) to the foreground visible state 
      */ 
     protected void onForeground(Intent intent) { 
     	super.onForeground(intent); 
     	System.out.println ("-------------onForeground"); 
     } 
     /**  
      * When the current Page is destroyed, trigger the execution of onStop
      */
     protected void onStop() {
     	super.onStop();
     	System.out.println("--------------onStop");
     }
}

4.2.4 Two rendering methods of Slice

Slice is equivalent to a web page. Views displayed in Slice are declared through components. Component loading in Slice supports two methods:

  • java code
  • xml layout file

onStartsetUIContextMethod: Executed when the Slice instance is created, used to load the view component of the current Slice, and load the view component by calling it in the onStart method

The setUIContext method provides 2 overloads:

setUIContext(int): Load the layout file under the resources/base/layout directory through the ID of the layout file

Complete the rendering of the page

setUIContext(ComponentContainer) : completes the page by loading a component created using Java code

rendering of

Rendering in XML**** mode

  • Create a layout file: ability_main_slice2.xml

    <?xml version="1.0" encoding="utf-8"?>
    <DirectionalLayout
        xmlns:ohos="http://schemas.huawei.com/res/ohos"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:orientation="vertical">
    
        <Text
            ohos:height="match_content"
            ohos:width="match_content"
            ohos:text="这是测试文本"
            ohos:text_color="#ff0000"
            ohos:text_size="40vp"></Text>
    
    </DirectionalLayout>
  • Load the layout file in Slice's onStart method:

    Every time a layout file is created (or each resource will create an ID), an ID will be generated, so the layout file calls the setUIContext(int) method

    @Override 
    protected void onStart(Intent intent) { 
        super.onStart(intent); 
        // Define the slice view component (java,xml) 
        // setUIContent(int); Load the layout file (xml) of the application as 
        the super. setUIContent(ResourceTable. Layout_ability_main_slice2); 
    }

Java rendering

  • Use Java code to create components and render them into slices

    public class MainAbilitySlice2 extends AbilitySlice { 
    
        @Override 
        protected void onStart(Intent intent) { 
            super.onStart(intent); 
            // define the slice view component (java, xml) 
            // setUIContent(int); load the application layout file (xml) as View of the current slice 
    // super.setUIContent(ResourceTable.Layout_ability_main_slice2); 
    
            // ComponentContainer (component container) 
            DirectionalLayout directionalLayout = new DirectionalLayout(this); 
            directionalLayout.setOrientation(Component.DRAG_VERTICAL); 
            // Component (component) 
            Text text = new Text(this); 
            text.setText("Hello Boys"); 
            text.setHeight(40); 
            text.setTextSize(40);
            // Put the component into the component container
            directionalLayout.addComponent(text); 
            // Render the component container into the slice 
            setUIContent(directionalLayout); 
        } 
    }

4.2.5 Navigation between AbilitySlices

A PageAbility can contain multiple Slices, and only one Slice can be displayed at a time, but it can be displayed in different

Jump between Slices - navigation between AbilitySlices

  • Add a button to MainAbilitySlice and listen to the click event of the button (refer to 4.3 slightly)

  • Create SecondAbilitySlice (omitted)

    <?xml version="1.0" encoding="utf-8"?> 
    <DirectionalLayout 
        xmlns:ohos="http://schemas.huawei.com/res/ohos" 
        ohos:height="match_parent" 
        ohos:width=" match_parent" 
        ohos:orientation="vertical"> 
    
        <!-- Save the image file to the resource/base/media directory PS: Do not start the file name with a number, because the name will be used as a variable name --> < 
        Image 
            ohos:height= "match_content" 
            ohos:width="match_parent" 
            ohos:image_src="$media:cat"> 
        </Image> 
    
    </DirectionalLayout>
    public class SecondAbilitySlice extends AbilitySlice {
    
        @Override
        protected void onStart(Intent intent) {
            super.onStart(intent);
            this.setUIContent(ResourceTable.Layout_ability_second);
        }
    }
  • Listen to the click event of the button in MainAbilitySlice and navigate to SecondAbilitySlice

    public class MainAbilitySlice extends AbilitySlice { 
        @Override 
        public void onStart(Intent intent) { 
            super.onStart(intent); 
            // There are 2 ways to render view components in the current slice: 
            // 1. Java code-based rendering 
            // 2. Render based on xml tags, for example: super.setUIContent(ResourceTable.Layout_ability_main); 
            super.setUIContent(ResourceTable.Layout_ability_main); 
    
            // 1. Get the button component with id=btn1 
            Button btn1 = (Button) this.findComponentById(ResourceTable.Id_btn1) ; 
    
            // 2. Set button event listener 
            MainAbilitySlice _this = this; 
            // a. Create event listener 
            Component.ClickedListener clickedListener = new Component.ClickedListener() { 
                @Override
                public void onClick(Component component) { 
                    //Click to SecondAbilitySlice 
                    // Jump from the current slice referred to by this to the new slice 
                    _this.present(new SecondAbilitySlice(), new Intent()); 
                } 
            }; 
            // b. Set the component's event listener 
            btn1.setClickedListener(clickedListener); 
    
        } 
    
    }

    Simplified version

    public class MainAbilitySlice extends AbilitySlice { 
        @Override 
        public void onStart(Intent intent) { 
            super.onStart(intent); 
            // There are 2 ways to render view components in the current slice: 
            // 1. Java code-based rendering 
            // 2. Render based on xml tags, for example: super.setUIContent(ResourceTable.Layout_ability_main); 
            super.setUIContent(ResourceTable.Layout_ability_main); 
    
            // 1. Get the button component with id=btn1 
            Button btn1 = (Button) this.findComponentById(ResourceTable.Id_btn1) ; 
            
    // //b. Set the component's event listener PS: simplified to lambda expression 
            // PS: simplified to lambda expression because the listener needs to implement the onclick method 
    // btn1.setClickedListener(clickedListener->{  
    // present(new SecondAbilitySlice (), new Intent() );
    // }); 
            
            / / b. Set the event listener of the component because there is only one method, you can omit the curly braces
            btn1.setClickedListener(clickedListener -> present(new SecondAbilitySlice(), new Intent()));
    
        }
    
    }

4.2.6 Value transfer problem between slices

Use the Intent object to realize value transfer between slices

  • MainAbilitySlice

    public class MainAbilitySlice extends AbilitySlice { 
        @Override 
        public void onStart(Intent intent) { 
            super.onStart(intent); 
            super.setUIContent(ResourceTable.Layout_ability_main); 
            // 1. Get the button component 
            Button with id=btn1 btn1 = (Button) this .findComponentById(ResourceTable.Id_btn1); 
            // b. Set the component's event listener 
            btn1.setClickedListener(clickedListener -> { 
                // The slice before the jump sets the data to be passed to the Intent object 
                Intent intent1 = new Intent() ; 
                intent1.setParam("productId", "101"); 
                present(new SecondAbilitySlice(), intent1); 
            }); 
    
        } 
    }
  • SecondAbilitySlice

    public class SecondAbilitySlice extends AbilitySlice { 
    
        @Override 
        protected void onStart(Intent intent) { 
            super.onStart(intent); 
            this.setUIContent(ResourceTable.Layout_ability_second); 
            // Get it from the intent object in the onStart method of the slice after the jump Data 
            if (intent != null) { 
                // Because intent.getParam() returns IntentParams, get IntentParams first and then get the value 
                IntentParams params = intent.getParams(); 
                String productId = (String) params.getParam(" productId"); 
                // Get the text component with id=text1 
                Text text = (Text) findComponentById(ResourceTable.Id_text1); 
                // Set the obtained product ID to the text component  
                text.setText(productId);
            } 
        } 
    }

4.3 Component event monitoring

4.3.1 Add buttons to the MainAbilitySlice layout file

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">

    <Image
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:image_src="$media:icon">
    </Image>

    <Text
        ohos:id="$+id:text_helloworld"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:background_element="$graphic:background_ability_main"
        ohos:layout_alignment="horizontal_center"
        ohos:text="$string:mainability_HelloWorld"
        ohos:text_size="40vp"/>
    <Button
        ohos:id="$+id:btn1"
        ohos:height="match_content"
        ohos:width="match_parent"
        ohos:padding="5vp"
        ohos:text="点我试试!"
        ohos:text_size="40vp"
        ohos:background_element="#a0b0c0"></Button>

</DirectionalLayout>

When we use it in Button $+id:btn1, this component will generate a unique identifier in ResourceTable

4.3.2 Listening to button click events

  • In the Slice class that loads the layout file, get the button component and set the click event listener

    package com.example.myapplicationdemo01.slice; 
    
    import com.example.myapplicationdemo01.ResourceTable; 
    import ohos.aafwk.ability.AbilitySlice; 
    import ohos.aafwk.content.Intent; 
    import ohos.agp.components.Button; 
    import ohos.agp. components.Component; 
    
    public class MainAbilitySlice extends AbilitySlice { 
        @Override 
        public void onStart(Intent intent) { 
            super.onStart(intent); 
            // There are 2 ways to render components in the current slice: 
            // 1. Java code-based rendering 
            // 2. Render based on xml tags, for example: super.setUIContent(ResourceTable.Layout_ability_main); 
            super.setUIContent(ResourceTable.Layout_ability_main); 
    
            // 1. Get the button component with id=btn1
            Button btn = (Button) this.findComponentById(ResourceTable.Id_btn1); 
    
            // 2. Set button event listener 
            // a. Create event listener 
            Component.ClickedListener clickedListener = new Component.ClickedListener(){ 
                @Override 
                public void onClick(Component component) { 
                    System.out.println("-------triggered a click event"); 
                } 
            }; 
            // b. Set the component's event listener 
            btn.setClickedListener(clickedListener); 
        } 
    }
    
  • You can use the same listener to listen to the events of multiple components. If you click on different components to perform different services, you can use component judgment to perform different services.

    // 1. Get the button component with id=btn1 
    Button btn1 = (Button) this.findComponentById(ResourceTable.Id_btn1); 
    Button btn2 = (Button) this.findComponentById(ResourceTable.Id_btn2); 
    
    // 2. Set the button event listener 
    / / a. Create an event listener 
    Component.ClickedListener clickedListener = new Component.ClickedListener(){ 
        @Override 
        public void onClick(Component component) { 
            // Component parameter indicates the listening component 
            if (component == btn1) { 
                System.out.println ("-------aaa"); 
            } else if (component == btn2) { 
                System.out.println("~~~~~~~~bbb"); 
            } 
    
        } 
    }; 
    // b .Set the component's event listener 
    btn1.setClickedListener(clickedListener);// output aaa
    btn2.setClickedListener(clickedListener);// output bbb

Guess you like

Origin blog.csdn.net/2301_76484015/article/details/130388160