2025-11-24 鴻蒙應(yīng)用開發(fā)進(jìn)階歷程:從零基礎(chǔ)到項目實踐的完整路徑

當(dāng)我第一次接觸鴻蒙系統(tǒng)時,面對全新的開發(fā)環(huán)境和架構(gòu)概念,內(nèi)心既充滿期待又有些忐忑。回顧這段成長歷程,我希望通過分享自己的學(xué)習(xí)路徑和實踐經(jīng)驗,幫助更多開發(fā)者順利走進(jìn)鴻蒙的世界。

**初識鴻蒙:環(huán)境搭建與基礎(chǔ)認(rèn)知**

起步階段最重要的是正確搭建開發(fā)環(huán)境。我選擇使用DevEco Studio作為主要開發(fā)工具,這是專為鴻蒙應(yīng)用開發(fā)定制的集成開發(fā)環(huán)境。

```typescript

// 第一個鴻蒙應(yīng)用:Hello World

// entry/src/main/ets/entryability/EntryAbility.ts

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

import window from '@ohos.window';

export default class EntryAbility extends UIAbility {

? onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

? ? console.log('EntryAbility onCreate');

? }

? onWindowStageCreate(windowStage: window.WindowStage): void {

? ? console.log('EntryAbility onWindowStageCreate');


? ? windowStage.loadContent('pages/Index', (err, data) => {

? ? ? if (err.code) {

? ? ? ? console.error('Failed to load the content. Cause: ' + JSON.stringify(err));

? ? ? ? return;

? ? ? }

? ? ? console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data));

? ? });

? }

}

```

對應(yīng)的頁面布局文件:

```typescript

// entry/src/main/ets/pages/Index.ets

@Entry

@Component

struct Index {

? @State message: string = 'Hello HarmonyOS'

? build() {

? ? Row() {

? ? ? Column() {

? ? ? ? Text(this.message)

? ? ? ? ? .fontSize(50)

? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? .onClick(() =><"1K.6370.HK"> {

? ? ? ? ? ? this.message = '歡迎來到鴻蒙世界!'

? ? ? ? ? })

? ? ? }

? ? ? .width('100%')

? ? }

? ? .height('100%')

? }

}

```

這個簡單的Hello World程序讓我理解了鴻蒙應(yīng)用的基本結(jié)構(gòu):Ability作為應(yīng)用組件,Page作為界面載體,通過聲明式UI構(gòu)建用戶界面。

**布局與組件:構(gòu)建用戶界面**

掌握了基礎(chǔ)后,我開始深入學(xué)習(xí)鴻蒙的UI組件系統(tǒng)。ArkTS語言結(jié)合聲明式語法,讓界面開發(fā)變得直觀而高效。

```typescript

// 綜合布局示例:用戶信息卡片

@Component

struct UserCard {

? @State isExpanded: boolean = false

? build() {

? ? Column() {

? ? ? // 用戶頭像和基本信息

? ? ? Row() {

? ? ? ? Image($r('app.media.user_avatar'))

? ? ? ? ? .width(60)

? ? ? ? ? .height(60)

? ? ? ? ? .borderRadius(30)


? ? ? ? Column() {

? ? ? ? ? Text('張三')

? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? .fontColor(Color.Black)

? ? ? ? ? Text('高級開發(fā)工程師')

? ? ? ? ? ? .fontSize(14)

? ? ? ? ? ? .fontColor(Color.Gray)

? ? ? ? }

? ? ? ? .alignItems(HorizontalAlign.Start)

? ? ? ? .margin({ left: 12 })


? ? ? ? Blank()


? ? ? ? Image($r(this.isExpanded ? 'app.media.arrow_up' : 'app.media.arrow_down'))

? ? ? ? ? .width(24)

? ? ? ? ? .height(24)

? ? ? ? ? .onClick(() => {

? ? ? ? ? ? this.isExpanded = !this.isExpanded

? ? ? ? ? })

? ? ? }

? ? ? .width('100%')

? ? ? .padding(16)

? ? ? // 可展開的詳細(xì)信息

? ? ? if (this.isExpanded) {

? ? ? ? Column() {

? ? ? ? ? Divider()

? ? ? ? ? Row() {

? ? ? ? ? ? Text('郵箱:')

? ? ? ? ? ? ? .fontSize(14)

? ? ? ? ? ? ? .fontColor(Color.Gray)

? ? ? ? ? ? Text('zhangsan@example.com')

? ? ? ? ? ? ? .fontSize<"2Y.6370.HK">(14)

? ? ? ? ? ? ? .fontColor(Color.Black)

? ? ? ? ? }

? ? ? ? ? .width('100%')

? ? ? ? ? .margin({ top: 8, bottom: 8 })


? ? ? ? ? Row() {

? ? ? ? ? ? Text('部門:')

? ? ? ? ? ? ? .fontSize(14)

? ? ? ? ? ? ? .fontColor(Color.Gray)

? ? ? ? ? ? Text('技術(shù)研發(fā)部')

? ? ? ? ? ? ? .fontSize(14)

? ? ? ? ? ? ? .fontColor(Color.Black)

? ? ? ? ? }

? ? ? ? ? .width('100%')

? ? ? ? ? .margin({ bottom: 8 })

? ? ? ? }

? ? ? ? .width('100%')

? ? ? ? .padding(16)

? ? ? }

? ? }

? ? .width('100%')

? ? .backgroundColor(Color.White)

? ? .borderRadius(12)

? ? .shadow({ radius: 8, color: '#1A000000', offsetX: 0, offsetY: 4 })

? ? .margin({ top: 12, left: 16, right: 16 })

? }

}

```

通過這個組件,我學(xué)會了狀態(tài)管理、條件渲染和事件處理等核心概念。

**數(shù)據(jù)管理與持久化存儲**

在實際應(yīng)用中,數(shù)據(jù)管理是必不可少的部分。我學(xué)習(xí)了鴻蒙提供的多種數(shù)據(jù)持久化方案。

```typescript

// 使用Preferences進(jìn)行輕量級數(shù)據(jù)存儲

import preferences from '@ohos.data.preferences';

@Entry

@Component

struct SettingsPage {

? @State username: string = ''

? @State notificationsEnabled: boolean = true

? private prefs: preferences.Preferences | null = null

? async aboutToAppear() <"3P.6370.HK">{

? ? try {

? ? ? this.prefs = await preferences.getPreferences(this.context, 'mySettings');

? ? ? this.username = await this.prefs.get('username', '');

? ? ? this.notificationsEnabled = await this.prefs.get('notificationsEnabled', true);

? ? } catch (err) {

? ? ? console.error('Failed to load preferences: ' + JSON.stringify(err));

? ? }

? }

? async saveSettings() {

? ? if (this.prefs) {

? ? ? await this.prefs.put('username', this.username);

? ? ? await this.prefs.put('notificationsEnabled', this.notificationsEnabled);

? ? ? await this.prefs.flush();

? ? ? promptAction.showToast({ message: '設(shè)置已保存' });

? ? }

? }

? build() {

? ? Column() {

? ? ? Text('應(yīng)用設(shè)置')

? ? ? ? .fontSize(24)

? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? .margin({ top: 20, bottom: 30 })

? ? ? List({ space: 12 }) {

? ? ? ? ListItem() {

? ? ? ? ? Row() {

? ? ? ? ? ? Text('用戶名')

? ? ? ? ? ? ? .fontSize(18)

? ? ? ? ? ? TextInput({ placeholder: '請輸入用戶名', text: this.username })

? ? ? ? ? ? ? .onChange((value: string) => {

? ? ? ? ? ? ? ? this.username = value

? ? ? ? ? ? ? })

? ? ? ? ? }

? ? ? ? ? .padding(16)

? ? ? ? }

? ? ? ? ListItem() {

? ? ? ? ? Row() {

? ? ? ? ? ? Text('啟用消息通知')

? ? ? ? ? ? ? .fontSize(18)

? ? ? ? ? ? Toggle({ type: ToggleType.Switch, isOn: this.notificationsEnabled })

? ? ? ? ? ? ? .onChange((value: boolean) => {

? ? ? ? ? ? ? ? this.notificationsEnabled = value

? ? ? ? ? ? ? })

? ? ? ? ? }

? ? ? ? ? .padding(16)

? ? ? ? }

? ? ? }

? ? ? .layoutWeight(1)

? ? ? Button('保存設(shè)置')

? ? ? ? .width('90%')

? ? ? ? .height(48)

? ? ? ? .fontSize(18)

? ? ? ? .onClick(() =><"4G.6370.HK"> {

? ? ? ? ? this.saveSettings()

? ? ? ? })

? ? ? ? .margin({ bottom: 20 })

? ? }

? ? .width('100%')

? ? .height('100%')

? ? .backgroundColor('#F5F5F5')

? }

}

```

**網(wǎng)絡(luò)請求與數(shù)據(jù)交互**

現(xiàn)代應(yīng)用離不開網(wǎng)絡(luò)通信,我學(xué)習(xí)了如何在鴻蒙應(yīng)用中發(fā)起網(wǎng)絡(luò)請求并處理響應(yīng)。

```typescript

// 網(wǎng)絡(luò)請求封裝示例

import http from '@ohos.net.http';

class ApiService {

? private static instance: ApiService;

? private httpRequest: http.HttpRequest;

? private constructor() {

? ? this.httpRequest = http.createHttp();

? }

? static getInstance(): ApiService {

? ? if (!ApiService.instance) {

? ? ? ApiService.instance = new ApiService();

? ? }

? ? return ApiService.instance;

? }

? async get<T>(url: string, params?: Record<string, string>): Promise<T> {

? ? try {

? ? ? let fullUrl = url;

? ? ? if (params) {

? ? ? ? const queryParams = new URLSearchParams(params).toString();

? ? ? ? fullUrl += '?' + queryParams;

? ? ? }

? ? ? const response = await this.httpRequest.request(fullUrl, {

? ? ? ? method: http.RequestMethod.GET,

? ? ? ? connectTimeout: 60000,

? ? ? ? readTimeout: 60000,

? ? ? });

? ? ? if (response.responseCode === 200) {

? ? ? ? return JSON.parse(response.result as string) as T;

? ? ? } else {

? ? ? ? throw new Error(`HTTP ${response.responseCode}: ${response.result}`);

? ? ? }

? ? } catch (err) {

? ? ? console.error('Request failed: ' + JSON.stringify(err));

? ? ? throw err;

? ? }

? }

? async post<T>(url: string, data: object): Promise<T> {

? ? try {

? ? ? const response = await this.httpRequest.request(url, {

? ? ? ? method: http.RequestMethod.POST,

? ? ? ? header: {

? ? ? ? ? 'Content-Type': 'application/json',

? ? ? ? },

? ? ? ? extraData: JSON.stringify(data),

? ? ? ? connectTimeout: 60000,

? ? ? ? readTimeout: <"5D.6370.HK">60000,

? ? ? });

? ? ? if (response.responseCode === 200) {

? ? ? ? return JSON.parse(response.result as string) as T;

? ? ? } else {

? ? ? ? throw new Error(`HTTP ${response.responseCode}: ${response.result}`);

? ? ? }

? ? } catch (err) {

? ? ? console.error('Request failed: ' + JSON.stringify(err));

? ? ? throw err;

? ? }

? }

}

// 在組件中使用API服務(wù)

@Component

struct NewsList {

? @State newsItems: NewsItem[] = []

? @State isLoading: boolean = true

? async aboutToAppear() {

? ? await this.loadNews();

? }

? async loadNews() {

? ? try {

? ? ? this.isLoading = true;

? ? ? const api = ApiService.getInstance();

? ? ? this.newsItems = await api.get<NewsItem[]>('https://api.example.com/news');

? ? } catch (err) {

? ? ? console.error('Failed to load news: ' + JSON.stringify(err));

? ? ? promptAction.showToast({ message: '加載失敗,請重試' });

? ? } finally {

? ? ? this.isLoading = false;

? ? }

? }

? build() {

? ? Column() {

? ? ? if (this.isLoading) {

? ? ? ? LoadingProgress()

? ? ? ? ? .color(Color.Blue)

? ? ? ? ? .margin({ top: 20 })

? ? ? ? Text('加載中...')

? ? ? ? ? .fontSize(16)

? ? ? ? ? .margin({ top: 12 })

? ? ? } else {

? ? ? ? List({ space: 8 }) {

? ? ? ? ? ForEach(this.newsItems, (item: NewsItem) => {

? ? ? ? ? ? ListItem() {

? ? ? ? ? ? ? NewsCard({ item: item })

? ? ? ? ? ? }

? ? ? ? ? }, (item: NewsItem) => item.id.toString())

? ? ? ? }

? ? ? ? .layoutWeight(1)

? ? ? }

? ? }

? ? .width('100%')<"6M.6370.HK">

? ? .height('100%')

? }

}

```

**分布式能力探索**

鴻蒙的分布式特性是其核心優(yōu)勢之一,我花時間學(xué)習(xí)了如何實現(xiàn)跨設(shè)備協(xié)同。

```typescript

// 分布式數(shù)據(jù)管理示例

import distributedObject from '@ohos.data.distributedDataObject';

class DistributedSession {

? private session: distributedObject.DataObject;


? constructor(sessionId: string) {

? ? this.session = distributedObject.createDataObject(sessionId);


? ? // 監(jiān)聽數(shù)據(jù)變化

? ? this.session.on('change', (fields: string[]) => {

? ? ? console.info('分布式數(shù)據(jù)發(fā)生變化: ' + JSON.stringify(fields));

? ? ? // 通知界面更新

? ? ? this.notifyDataChange();

? ? });

? }

? // 設(shè)置共享數(shù)據(jù)

? setValue(key: string, value: any): void {

? ? this.session[key] = value;

? ? this.session.save().then(() => {

? ? ? console.info('數(shù)據(jù)保存成功');

? ? }).catch((err) => {

? ? ? console.error('數(shù)據(jù)保存失敗: ' + JSON.stringify(err));

? ? });

? }

? // 獲取共享數(shù)據(jù)

? getValue(key: string): any {

? ? return this.session[key];

? }

? // 設(shè)備狀態(tài)同步

? syncDeviceStatus(deviceId: string, status: DeviceStatus): void {

? ? this.setValue(`device_${deviceId}`, status);

? }

}

// 在組件中使用分布式能力

@Entry

@Component

struct CollaborativeWhiteboard {

? private distSession: DistributedSession = new DistributedSession('whiteboard_session');

? @State strokes: Stroke[] = []

? @State connectedDevices: string[] = []

? aboutToAppear() {

? ? this.distSession.setValue('whiteboard_data', this.strokes);

? }

? build() {

? ? Column() <"UF.5283.HK">{

? ? ? // 設(shè)備連接狀態(tài)顯示

? ? ? Row() {

? ? ? ? Text('協(xié)作設(shè)備:')

? ? ? ? ? .fontSize(16)

? ? ? ? ForEach(this.connectedDevices, (device: string) => {

? ? ? ? ? Text(device)

? ? ? ? ? ? .fontSize(14)

? ? ? ? ? ? .backgroundColor(Color.Green)

? ? ? ? ? ? .padding(4)

? ? ? ? ? ? .margin({ left: 8 })

? ? ? ? })

? ? ? }

? ? ? .padding(12)

? ? ? // 畫板區(qū)域

? ? ? Canvas(this.context)

? ? ? ? .width('100%')

? ? ? ? .height('80%')

? ? ? ? .backgroundColor(Color.White)

? ? ? ? .onTouch((event: TouchEvent) => {

? ? ? ? ? this.handleTouch(event);

? ? ? ? })

? ? ? // 工具欄

? ? ? Toolbar({

? ? ? ? onColorChange: (color: string) => this.setStrokeColor(color),

? ? ? ? onClear: () => this.clearWhiteboard()

? ? ? })

? ? }

? }

? private handleTouch(event: TouchEvent): void {

? ? // 處理觸摸事件并同步到其他設(shè)備

? ? const newStroke = this.createStrokeFromTouch(event);

? ? this.strokes.push(newStroke);

? ? this.distSession.setValue('whiteboard_data', this.strokes);

? }

}

```

**項目實戰(zhàn):天氣預(yù)報應(yīng)用**

將所學(xué)知識整合起來,我開發(fā)了一個功能完整的天氣預(yù)報應(yīng)用。

```typescript

// 主頁面組件

@Entry

@Component

struct WeatherApp {

? @State currentWeather: WeatherData | null = null

? @State forecast: ForecastItem[] = []

? @State currentCity: string = '北京市'

? async aboutToAppear() {

? ? await this.loadWeatherData();

? }

? async loadWeatherData() {

? ? try {

? ? ? const api = ApiService.getInstance();


? ? ? // 獲取當(dāng)前天氣

? ? ? this.currentWeather = await api.get<WeatherData>(

? ? ? ? `https://api.weather.com/current?city=${this.currentCity}`

? ? ? );

? ? ? // 獲取天氣預(yù)報

? ? ? this.forecast = await api.get<ForecastItem[]>(

? ? ? ? `https://api.weather.com/forecast?city=${this.currentCity}`

? ? ? );

? ? } catch (err) {

? ? ? console.error('Failed to load weather data: ' + JSON.stringify(err));

? ? }

? }

? build() {

? ? Column() {

? ? ? // 標(biāo)題欄

? ? ? Row() {

? ? ? ? Text('天氣預(yù)報')

? ? ? ? ? .fontSize(24)

? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? .fontColor(Color.White)


? ? ? ? Blank()


? ? ? ? Button('切換城市')

? ? ? ? ? .fontSize(14)

? ? ? ? ? .backgroundColor(Color.Transparent)

? ? ? ? ? .fontColor(Color.White)

? ? ? ? ? .onClick(() => {

? ? ? ? ? ? this.showCitySelector();

? ? ? ? ? })

? ? ? }

? ? ? .width('100%')

? ? ? .padding(20)

? ? ? .backgroundColor(Color.Blue)

? ? ? Scroll() {

? ? ? ? Column() {

? ? ? ? ? // 當(dāng)前天氣信息

? ? ? ? ? if (this.currentWeather) {

? ? ? ? ? ? CurrentWeather({ weather: this.currentWeather })

? ? ? ? ? }

? ? ? ? ? // 天氣預(yù)報列表

? ? ? ? ? Text('未來預(yù)報')

? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? .fontWeight(FontWeight.Medium)

? ? ? ? ? ? .margin({ top: 24, bottom: 16, left: 16 })


? ? ? ? ? ForEach(this.forecast, (item: ForecastItem) => {

? ? ? ? ? ? ForecastRow({ item: item })

? ? ? ? ? })

? ? ? ? }

? ? ? }

? ? ? .layoutWeight(1)

? ? }

? ? .width('100%')

? ? .height('100%')

? }

}

```

通過這個完整的學(xué)習(xí)路徑,我從一個對鴻蒙開發(fā)一無所知的"小白",逐步成長為能夠獨立開發(fā)應(yīng)用的開發(fā)者。這個過程雖然充滿挑戰(zhàn),但每解決一個問題、每完成一個功能,都帶來了巨大的成就感。鴻蒙生態(tài)正在快速發(fā)展,我相信現(xiàn)在正是學(xué)習(xí)和參與的最佳時機。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容