2023-12-05 鴻蒙Harmony開發(fā)初探

鴻蒙Harmony開發(fā)初探

個(gè)人博客主頁https://guofeng007.com/

一盐肃、背景

9月25日華為秋季全場(chǎng)景新品發(fā)布會(huì),余承東宣布鴻蒙HarmonyOS NEXT蓄勢(shì)待發(fā)饵撑,不再支持安卓應(yīng)用。網(wǎng)易有道泌霍、同程旅行闸迷、美團(tuán)控汉、國航、阿里等公司先后宣布啟動(dòng)鴻蒙原生應(yīng)用開發(fā)工作钟病。

二萧恕、鴻蒙Next介紹

HarmonyOS是一款面向萬物互聯(lián)刚梭,全新的分布式操作系統(tǒng)。

1票唆、鴻蒙Next(5.0)系統(tǒng)底座全棧自研朴读,去掉了傳統(tǒng)的**AOSP代碼。

2惰说、僅支持鴻蒙內(nèi)核和鴻蒙系統(tǒng)的應(yīng)用磨德。

3、業(yè)內(nèi)人士向證券時(shí)報(bào)公司記者表示:“華為內(nèi)部確實(shí)有這計(jì)劃吆视,就是明年Q1推出不兼容安卓的鴻蒙版本典挑,但目前內(nèi)部還沒有下發(fā)相關(guān)通知,所以具體何時(shí)推出暫不明確

三啦吧、鴻蒙系統(tǒng)開發(fā)

鴻蒙系統(tǒng)架構(gòu)

[圖片上傳失敗...(image-14ede8-1701759810425)]

3.1 IDE

HUAWEI DevEco Studio 基于IntelliJ IDEA Community開源版本定制開發(fā)您觉,支持HarmonyOS和OpenHarmony應(yīng)用及服務(wù)開發(fā)。

下載地址:https://developer.harmonyos.com/cn/develop/deveco-studio/

3.2 示例講解

github地址: https://github.com/guofeng007/Harmonydemo

界面效果:

[圖片上傳失敗...(image-b2a329-1701759810426)]

全局配置

[圖片上傳失敗...(image-398ef1-1701759810426)]

{
  "app": {
  // 最重要的是包名授滓,版本號(hào)琳水,圖片和app名稱
    "bundleName": "com.example.myapplication", 
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "icon": "$media:app_icon",
    "label": "$string:app_name"
  }
}

模塊配置

{
  "module": {
    "name": "entry",
    "type": "entry",
    // 模塊生命周期入口 
    "srcEntry": "./ets/MyAbilityStage.ts", 
    "description": "$string:module_desc",
    // 應(yīng)用入口
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
      // 入口具體聲明配置,參考android
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ]
  }
}

APP模塊全局聲明周期

import AbilityStage from '@ohos.app.ability.AbilityStage';

export default class MyAbilityStage extends AbilityStage {
  onCreate() {
    // 應(yīng)用的HAP在首次加載的時(shí)般堆,為該Module初始化操作
  }
  onAcceptWant(want) {
    // 僅specified模式下觸發(fā)
    return "MyAbilityStage";
  }
}

入口任務(wù)棧

這個(gè)比較重要在孝,對(duì)從安卓轉(zhuǎn)過來的同學(xué)來說,可以理解為一個(gè)TaskStack淮摔,在手機(jī)的多任務(wù)欄私沮,顯示為一個(gè)任務(wù),是一個(gè)任務(wù)容器和橙。

EntryAbility 繼承自 UIAbility 并實(shí)現(xiàn)了其中的 onCreate 仔燕、onDestroy 、 onWindowStageCreate 魔招、 onWindowStageDestroy 晰搀、 onForeground 、 onBackground 等方法办斑,顯然外恕,這些方法就是這個(gè) ability 的生命周期。
然后在 onWindowStageCreate 生命周期中通過 windowStage.loadContent 加載了 pages/Index 的內(nèi)容乡翅,pages/Index就相當(dāng)于我們的入口UI頁面鳞疲。

UIAbility介紹:
UIAbility是一種包含用戶界面的應(yīng)用組件,主要用于和用戶進(jìn)行交互峦朗。UIAbility也是系統(tǒng)調(diào)度的單元建丧,為應(yīng)用提供窗口在其中繪制界面。
每一個(gè)UIAbility實(shí)例波势,都對(duì)應(yīng)于一個(gè)最近任務(wù)列表中的任務(wù)翎朱。
一個(gè)應(yīng)用可以有一個(gè)UIAbility橄维,也可以有多個(gè)UIAbility。
一個(gè)UIAbility可以對(duì)應(yīng)于多個(gè)頁面拴曲。

[圖片上傳失敗...(image-1d0459-1701759810426)]

  • UIAbility&Window生命周期

[圖片上傳失敗...(image-5b8a02-1701759810426)]

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy() {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground() {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground() {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

路由配置

{
  "src": [
    "pages/Index",
    "pages/routes/FirstPage",
    "pages/routes/SecondPage",
    "pages/routes/WebComponent"
  ]
}

3.3 ArkUI

ArkUI的基本單元是組件澈灼,組件是一個(gè)獨(dú)立子頁面或者子模塊竞川。示例代碼有注釋,包含頁面UI組件叁熔,狀態(tài)委乌,route跳轉(zhuǎn)。

組件聲明周期

[圖片上傳失敗...(image-30c9a4-1701759810426)]

import router from '@ohos.router'

@Entry //@Entry表示該自定義組件為入口組件
@Component //@Component表示自定義組件
struct Index {
  //@State表示組件中的狀態(tài)變量荣回,狀態(tài)變量變化會(huì)觸發(fā)UI刷新
  @State count: number = 1
  @State url: string = "https://img1.baidu.com/it/u=3302184040,3713353210&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
  private product: string[] = ['PC遭贸。', "平板。", `手環(huán)心软。`]
  //UI描述:以聲明式的方式來描述UI的結(jié)構(gòu)壕吹,例如build()方法中的代碼塊。
  build() {
    //系統(tǒng)組件:ArkUI框架中默認(rèn)內(nèi)置的基礎(chǔ)和容器組件,比如示例中的Row删铃、Column耳贬、Text
    //不允許在UI描述里直接使用聲明局部變量
    // let a = 1 ERROR
    Row() {
      Column() {
        Button("Page跳轉(zhuǎn)")
          .onClick(()=>{
            router.pushUrl({ url: "pages/routes/FirstPage", params: {
              param: "第一個(gè)頁面?zhèn)鱽淼闹?,
            } })
          })
        Button("Webview跳轉(zhuǎn)")
          .onClick(()=>{
            router.pushUrl({ url: "pages/routes/WebComponent", params: {
              param: "第一個(gè)頁面?zhèn)鱽淼闹?,
            } })
          })
        Text(this.count.toString())
          //屬性方法:組件可以通過鏈?zhǔn)秸{(diào)用配置多項(xiàng)屬性,如fontSize()猎唁、width()咒劲、height()、backgroundColor()等
          .fontWeight(FontWeight.Bold)
            //定義擴(kuò)展原生組件樣式
          .setCustomText(30)
          }
         }
       }
}

3.4 Webview

在原生APP組件開發(fā)過程中胖秒,很多活動(dòng)頁面都是h5實(shí)現(xiàn)缎患,但是需要很多原生的能力慕的,比如相機(jī)阎肝,這種情況下就需要類似JsBridge方式的WebView

import webView from '@ohos.web.webview';

@Entry
@Component
struct WebComponent {
  controller: webView.WebviewController = new webView.WebviewController();
  webUrl: string = 'https://www.baidu.com/'
  jsBridge = {
    callNaMethod() {
      console.log("H5調(diào)用Native方法")

    }
  }

  aboutToAppear(){
    webView.WebviewController.setWebDebuggingAccess(true)
  }

  build() {
    Stack() {
      //加載網(wǎng)絡(luò)url
      // Web({ src: this.webUrl, controller: this.controller })
      //加載本地html
      Web({ src: $rawfile("demo.html"), controller: this.controller })
        //允許訪問本地文件
        .fileAccess(true)
          //設(shè)置是否允許執(zhí)行JavaScript腳本
        .javaScriptAccess(true)
          //注入JavaScript對(duì)象到window對(duì)象中,并在window對(duì)象中調(diào)用該對(duì)象的方法
        .javaScriptProxy({
          object: this.jsBridge,
          name: "jsBridge",
          methodList: ["callNaMethod"],
          controller: this.controller
        })
        .onPageEnd(event => {
          //異步執(zhí)行JavaScript腳本 調(diào)用H5方法
          this.controller.runJavaScript("callH5Method()")
            .then(result => {
              console.log(`H5返回值=${result}`)
            })
            .catch(error => {
              console.error("error: " + error);
            })
        })
    }
  }
}

測(cè)試html

<!DOCTYPE html>

<html>

<body>




<!--調(diào)用原生方法-->
<button type="button" onclick="window.jsBridge.callNaMethod()">點(diǎn)擊調(diào)用原生界面方法</button>
</body>

<script type="text/javascript">
  function callH5Method() {
     
      return "從H5返回"
  }
</script>
</html>

3.5 Devtools調(diào)試webview

  1. 代碼中允許webview調(diào)試 web_webview.WebviewController.setWebDebuggingAccess(true);
// xxx.ets
import web_webview from '@ohos.web.webview';

@Entry
@Component
struct WebComponent {
  controller: web_webview.WebviewController = new web_webview.WebviewController();
  aboutToAppear() {
    // 配置web開啟調(diào)試模式
    web_webview.WebviewController.setWebDebuggingAccess(true);
  }
  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
    }
  }
}
  1. 用hdc命令行工具

(需要全局設(shè)置path /Users/你的用戶名/Library/Huawei/Sdk/hmscore/3.1.0/toolchains/)

// 添加映射 

hdc fport tcp:9222 tcp:9222 

// 查看映射 

hdc fport ls
  1. 在PC端chrome瀏覽器地址欄中輸入chrome://inspect/#devices肮街,頁面識(shí)別到設(shè)備后风题,就可以開始頁面調(diào)試。調(diào)試效果如下:
image-20231205135433565.png

總結(jié)

鴻蒙整體上開發(fā)很像Kotlin Compose嫉父,也借鑒了很多大前端比如Vue的響應(yīng)式編程理念沛硅,有以上經(jīng)驗(yàn)的很容易上手。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绕辖,一起剝皮案震驚了整個(gè)濱河市摇肌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仪际,老刑警劉巖围小,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昵骤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肯适,警方通過查閱死者的電腦和手機(jī)变秦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來框舔,“玉大人蹦玫,你說我怎么就攤上這事×跣澹” “怎么了樱溉?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)纬凤。 經(jīng)常有香客問我饺窿,道長(zhǎng),這世上最難降的妖魔是什么移斩? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任肚医,我火速辦了婚禮,結(jié)果婚禮上向瓷,老公的妹妹穿的比我還像新娘肠套。我一直安慰自己,他們只是感情好猖任,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布你稚。 她就那樣靜靜地躺著,像睡著了一般朱躺。 火紅的嫁衣襯著肌膚如雪刁赖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天长搀,我揣著相機(jī)與錄音宇弛,去河邊找鬼。 笑死源请,一個(gè)胖子當(dāng)著我的面吹牛枪芒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谁尸,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舅踪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了良蛮?” 一聲冷哼從身側(cè)響起抽碌,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎决瞳,沒想到半個(gè)月后货徙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泽裳,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年破婆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涮总。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡祷舀,死狀恐怖瀑梗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裳扯,我是刑警寧澤抛丽,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站饰豺,受9級(jí)特大地震影響亿鲜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冤吨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一蒿柳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漩蟆,春花似錦垒探、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捺癞,卻和暖如春夷蚊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背髓介。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國打工惕鼓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人版保。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓呜笑,卻偏偏與公主長(zhǎng)得像夫否,于是被迫代替她去往敵國和親彻犁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容