鴻蒙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)]
-
UIAbility的啟動(dòng)模式
是指UIAbility實(shí)例在啟動(dòng)時(shí)的不同呈現(xiàn)狀態(tài)争舞。針對(duì)不同的業(yè)務(wù)場(chǎng)景,系統(tǒng)提供了三種啟動(dòng)模式:
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
- 代碼中允許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 })
}
}
}
- 用hdc命令行工具
(需要全局設(shè)置path /Users/你的用戶名/Library/Huawei/Sdk/hmscore/3.1.0/toolchains/)
// 添加映射
hdc fport tcp:9222 tcp:9222
// 查看映射
hdc fport ls
- 在PC端chrome瀏覽器地址欄中輸入chrome://inspect/#devices肮街,頁面識(shí)別到設(shè)備后风题,就可以開始頁面調(diào)試。調(diào)試效果如下:
總結(jié)
鴻蒙整體上開發(fā)很像Kotlin Compose嫉父,也借鑒了很多大前端比如Vue的響應(yīng)式編程理念沛硅,有以上經(jīng)驗(yàn)的很容易上手。