【OpenHarmony】鸿蒙应用开发实战指南:构建网络数据列表应用

【OpenHarmony】鸿蒙应用开发实战指南:构建网络数据列表应用

鸿蒙应用开发实战指南:构建网络数据列表应用

在这里插入图片描述
前言:本文从零开始,详细介绍如何使用HarmonyOS ArkTS语言开发一个具备网络请求和数据列表展示功能的应用。涵盖工程搭建、网络封装、UI开发、错误处理等核心知识点,适合鸿蒙开发入门者学习参考。

一、开发环境准备

1.1 必备软件清单

软件版本要求用途下载地址
Node.js16.x+JavaScript运行环境nodejs.org
DevEco Studio4.0+鸿蒙官方IDEdeveloper.huawei.com
Git最新版版本控制工具git-scm.com

1.2 Git全局配置

# 配置用户信息git config --global user.name "YourName"git config --global user.email "[email protected]"# 配置默认分支名git config --global init.defaultBranch main # 配置凭证缓存(避免频繁输入密码)git config --global credential.helper store 

1.3 代码仓库创建

在Gitee/AtomGit等平台创建新仓库:

仓库配置建议

  • 仓库名:harmonyos-network-demo
  • 可见性:公开
  • 许可证:MIT
  • 初始化选项:添加README、.gitignore(选择OpenHarmony模板)

1.4 本地仓库初始化

# 克隆仓库git clone https://gitee.com/your-username/harmonyos-network-demo.git cd harmonyos-network-demo # 或本地初始化后关联远程git init gitadd.git commit -m"chore: 初始化鸿蒙网络请求示例项目"git branch -M main git remote add origin https://gitee.com/your-username/harmonyos-network-demo.git git push -u origin main 

二、工程创建与目录结构

2.1 创建鸿蒙工程

  1. 打开DevEco Studio,点击「Create Project」
  2. 选择「Empty Ability」模板
  3. 配置工程信息:
    • 工程名:HarmonyoNetworkList
    • 包名:com.example.networklist
    • 保存位置:选择刚才克隆的仓库目录
    • SDK版本:API 10+
    • 设备类型:Phone

2.2 推荐目录结构

HarmonyoNetworkList/ ├── entry/ │ └── src/ │ └── main/ │ ├── ets/ # ArkTS源码目录 │ │ ├── entryability/ # Ability入口 │ │ ├── pages/ # 页面目录 │ │ ├── model/ # 数据模型 │ │ ├── utils/ # 工具类 │ │ └── common/ # 公共资源 │ │ ├── constants/ # 常量定义 │ │ └── styles/ # 样式配置 │ ├── resources/ # 资源文件 │ │ ├── base/ # 基础资源 │ │ │ ├── element/ # 元素资源 │ │ │ ├── media/ # 媒体资源 │ │ │ └── profile/ # 配置文件 │ │ └── rawfile/ # 原始文件 │ └── module.json5 # 模块配置 ├── oh-package.json5 # 依赖管理 ├── build-profile.json5 # 构建配置 └── app.json5 # 应用配置 

三、核心配置文件详解

3.1 依赖管理(oh-package.json5)

{ "name": "entry", "version": "1.0.1", "description": "HarmonyOS网络请求与列表展示示例", "main": "", "author": "", "license": "MIT", "dependencies": {}, "devDependencies": { "@ohos/hypium": "1.0.16" } } 

3.2 模块配置(module.json5)

{ "module": { "name": "entry", "type": "entry", "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ "default", "tablet" ], "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", "abilities": [ { "name": "EntryAbility", "srcEntry": "./ets/entryability/EntryAbility.ets", "description": "$string:EntryAbility_desc", "icon": "$media:app_icon", "label": "$string:EntryAbility_label", "startWindowIcon": "$media:icon", "startWindowBackground": "$color:start_window_background", "exported": true, "skills": [ { "entities": [ "entity.system.home" ], "actions": [ "action.system.home" ] } ] } ], "requestPermissions": [ { "name": "ohos.permission.INTERNET", "reason": "$string:internet_permission_reason", "usedScene": { "abilities": [ "EntryAbility" ], "when": "inuse" } } ] } } 

3.3 页面路由配置(main_pages.json)

{ "src": [ "pages/TaskListPage" ] } 

3.4 应用级配置(app.json5)

{ "app": { "bundleName": "com.example.networklist", "vendor": "example", "versionCode": 1000000, "versionName": "1.0.0", "icon": "$media:app_icon", "label": "$string:app_name", "description": "$string:app_description", "targetSDKVersion": 10, "apiReleaseType": "Release" } } 

3.5 字符串资源配置

// resources/base/element/string.json { "string": [ { "name": "app_name", "value": "任务清单" }, { "name": "app_description", "value": "基于HarmonyOS的网络请求与列表展示示例" }, { "name": "module_desc", "value": "网络请求与数据列表示例模块" }, { "name": "EntryAbility_desc", "value": "任务清单应用入口" }, { "name": "EntryAbility_label", "value": "任务清单" }, { "name": "internet_permission_reason", "value": "需要网络权限以获取任务数据" }, { "name": "loading_text", "value": "加载中..." }, { "name": "error_text", "value": "加载失败,请重试" }, { "name": "retry_text", "value": "重试" }, { "name": "empty_text", "value": "暂无数据" } ] } 

3.6 颜色资源配置

// resources/base/element/color.json { "color": [ { "name": "start_window_background", "value": "#FFFFFF" }, { "name": "primary_color", "value": "#0A59F7" }, { "name": "background_color", "value": "#F5F5F5" }, { "name": "card_background", "value": "#FFFFFF" }, { "name": "text_primary", "value": "#182431" }, { "name": "text_secondary", "value": "#99182431" }, { "name": "divider_color", "value": "#E5E5E5" }, { "name": "success_color", "value": "#00C853" }, { "name": "error_color", "value": "#FF5252" } ] } 

四、数据模型定义

4.1 任务数据模型

// entry/src/main/ets/model/TaskModel.ets/** * 任务数据项模型 */exportinterfaceTaskItem{ id:number;// 任务ID title:string;// 任务标题 completed:boolean;// 完成状态 userId:number;// 用户ID}/** * 网络响应基类 */exportinterfaceApiResponse<T>{ data:T;// 响应数据 code:number;// 响应码 message:string;// 响应消息}/** * 列表响应数据 */exportinterfaceListResponse<T>{ items:T[];// 数据列表 total:number;// 总数量 page:number;// 当前页码 pageSize:number;// 每页大小}

4.2 常量定义

// entry/src/main/ets/common/constants/ApiConstants.ets/** * API常量定义 */exportclassApiConstants{// 基础URLprivatestaticreadonlyBASE_URL='https://jsonplaceholder.typicode.com';// API端点staticreadonlyTASKS_ENDPOINT='/todos';staticreadonlyTASK_DETAIL_ENDPOINT=(id:number)=>`/todos/${id}`;staticreadonlyUSER_TASKS_ENDPOINT=(userId:number)=>`/todos?userId=${userId}`;// 完整URL构建staticgetFullUrl(endpoint:string):string{return`${this.BASE_URL}${endpoint}`;}// 超时时间(毫秒)staticreadonlyCONNECT_TIMEOUT=10000;staticreadonlyREAD_TIMEOUT=15000;}/** * 业务常量 */exportclassBusinessConstants{// 每页加载数量staticreadonlyPAGE_SIZE=20;// 状态码staticreadonlySUCCESS_CODE=200;staticreadonlyERROR_CODE=-1;// 缓存时间(秒)staticreadonlyCACHE_DURATION=300;}

五、网络请求封装

5.1 HTTP请求工具类

// entry/src/main/ets/utils/HttpUtil.etsimport http from'@ohos.net.http';import{ BusinessConstants }from'../common/constants/ApiConstants';/** * HTTP请求配置 */interfaceRequestConfig{ method?: http.RequestMethod; header?: Record<string,string>; readTimeout?:number; connectTimeout?:number; extraData?:string| Object | ArrayBuffer;}/** * HTTP响应数据 */interfaceHttpResponse<T>{ data:T; statusCode:number; headers: Record<string,string>;}/** * HTTP请求工具类 */exportclassHttpUtil{/** * GET请求 * @param url 请求地址 * @param params 请求参数 * @param config 请求配置 */staticasyncget<T>( url:string, params?: Record<string,string>, config?: RequestConfig ):Promise<HttpResponse<T>>{// 构建带参数的URLlet fullUrl = url;if(params && Object.keys(params).length >0){const queryString = Object.keys(params).map(key =>`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&'); fullUrl =`${url}?${queryString}`;}returnthis.request<T>(fullUrl,{ method: http.RequestMethod.GET, readTimeout: BusinessConstants.CONNECT_TIMEOUT, connectTimeout: BusinessConstants.READ_TIMEOUT,...config });}/** * POST请求 * @param url 请求地址 * @param data 请求数据 * @param config 请求配置 */staticasyncpost<T>( url:string, data?: Object |string, config?: RequestConfig ):Promise<HttpResponse<T>>{returnthis.request<T>(url,{ method: http.RequestMethod.POST, extraData: data, readTimeout: BusinessConstants.READ_TIMEOUT, connectTimeout: BusinessConstants.CONNECT_TIMEOUT,...config });}/** * 通用请求方法 * @param url 请求地址 * @param config 请求配置 */privatestaticasyncrequest<T>( url:string, config: RequestConfig ={}):Promise<HttpResponse<T>>{// 创建HTTP请求对象const httpRequest = http.createHttp();try{// 设置默认请求头const defaultHeaders: Record<string,string>={'Content-Type':'application/json','Accept':'application/json'};// 合并请求头const headers ={...defaultHeaders,...config.header };// 发起请求const response =await httpRequest.request(url,{ method: config.method || http.RequestMethod.GET, header: headers, readTimeout: config.readTimeout ||15000, connectTimeout: config.connectTimeout ||10000, extraData: config.extraData });// 解析响应数据let responseData:T;const contentType = response.headers?.['Content-Type']||'';const responseType = response.responseType;switch(responseType){case http.HttpResponseType.STRING:if(contentType.includes('application/json')){ responseData =JSON.parse(response.result asstring)asT;}else{ responseData = response.result asT;}break;case http.HttpResponseType.ARRAY_BUFFER: responseData = response.result asT;break;default: responseData = response.result asT;}return{ data: responseData, statusCode: response.responseCode, headers: response.headers };}catch(error){thrownewError(`请求失败: ${error.message || error}`);}finally{// 销毁请求对象 httpRequest.destroy();}}}

5.2 任务数据服务

// entry/src/main/ets/utils/TaskService.etsimport{ HttpUtil }from'./HttpUtil';import{ TaskItem }from'../model/TaskModel';import{ ApiConstants }from'../common/constants/ApiConstants';/** * 任务数据服务类 */exportclassTaskService{/** * 获取所有任务列表 */staticasyncgetAllTasks():Promise<TaskItem[]>{const url = ApiConstants.getFullUrl(ApiConstants.TASKS_ENDPOINT);const response =await HttpUtil.get<TaskItem[]>(url);return response.data;}/** * 获取单个任务详情 * @param taskId 任务ID */staticasyncgetTaskDetail(taskId:number):Promise<TaskItem>{const url = ApiConstants.getFullUrl(ApiConstants.TASK_DETAIL_ENDPOINT(taskId));const response =await HttpUtil.get<TaskItem>(url);return response.data;}/** * 获取指定用户的任务 * @param userId 用户ID */staticasyncgetUserTasks(userId:number):Promise<TaskItem[]>{const url = ApiConstants.getFullUrl(ApiConstants.USER_TASKS_ENDPOINT(userId));const response =await HttpUtil.get<TaskItem[]>(url);return response.data;}/** * 按完成状态筛选任务 * @param completed 是否完成 */staticasyncgetTasksByStatus(completed:boolean):Promise<TaskItem[]>{const url = ApiConstants.getFullUrl(ApiConstants.TASKS_ENDPOINT);const response =await HttpUtil.get<TaskItem[]>(url,{ completed:String(completed)});return response.data;}}

六、UI组件开发

6.1 任务列表页面

// entry/src/main/ets/pages/TaskListPage.etsimport{ TaskItem }from'../model/TaskModel';import{ TaskService }from'../utils/TaskService';import promptAction from'@ohos.promptAction';/** * 任务状态枚举 */enum LoadState {IDLE='idle',LOADING='loading',SUCCESS='success',ERROR='error'}/** * 任务列表页面 */@Entry@Component struct TaskListPage {// 任务列表数据@Stateprivate taskList: TaskItem[]=[];// 加载状态@Stateprivate loadState: LoadState = LoadState.IDLE;// 错误信息@Stateprivate errorMessage:string='';// 是否正在下拉刷新@Stateprivate isRefreshing:boolean=false;/** * 页面即将出现时加载数据 */aboutToAppear():void{this.loadTaskData();}/** * 加载任务数据 */privateasyncloadTaskData():Promise<void>{this.loadState = LoadState.LOADING;this.errorMessage ='';try{const tasks =await TaskService.getAllTasks();this.taskList = tasks;this.loadState = LoadState.SUCCESS;}catch(error){this.errorMessage = error.message ||'加载失败,请重试';this.loadState = LoadState.ERROR;console.error(`[TaskListPage] 加载失败: ${this.errorMessage}`);}}/** * 下拉刷新 */privateasynconRefresh():Promise<void>{this.isRefreshing =true;awaitthis.loadTaskData();this.isRefreshing =false;}/** * 重试加载 */privateonRetry():void{this.loadTaskData();}/** * 任务项点击事件 */privateonTaskClick(task: TaskItem):void{ promptAction.showToast({ message:`任务: ${task.title}\n状态: ${task.completed ?'已完成':'进行中'}`, duration:2000});}/** * 切换任务完成状态 */privatetoggleTaskStatus(task: TaskItem):void{ task.completed =!task.completed;// 更新UIconst index =this.taskList.findIndex(item => item.id === task.id);if(index !==-1){this.taskList.splice(index,1,{...task });}}/** * 构建加载中UI */@BuilderprivateLoadingBuilder(){Column(){LoadingProgress().width(48).height(48).color($r('app.color.primary_color'))Text($r('app.string.loading_text')).fontSize(16).fontColor($r('app.color.text_secondary')).margin({ top:16})}.width('100%').height('100%').justifyContent(FlexAlign.Center)}/** * 构建错误UI */@BuilderprivateErrorBuilder(){Column({ space:16}){Image($r('app.media.ic_error')).width(80).height(80).fillColor($r('app.color.error_color'))Text(this.errorMessage ||$r('app.string.error_text')).fontSize(16).fontColor($r('app.color.text_secondary')).textAlign(TextAlign.Center)Button($r('app.string.retry_text')).onClick(()=>this.onRetry()).type(ButtonType.Capsule).backgroundColor($r('app.color.primary_color'))}.width('100%').height('100%').justifyContent(FlexAlign.Center).padding(24)}/** * 构建空数据UI */@BuilderprivateEmptyBuilder(){Column({ space:16}){Image($r('app.media.ic_empty')).width(120).height(120).fillColor($r('app.color.text_secondary'))Text($r('app.string.empty_text')).fontSize(16).fontColor($r('app.color.text_secondary'))}.width('100%').height('100%').justifyContent(FlexAlign.Center)}/** * 构建任务项UI */@BuilderprivateTaskItemBuilder(task: TaskItem, index:number){Row(){// 状态图标Image(task.completed ?$r('app.media.ic_check_circle'):$r('app.media.ic_radio_unchecked')).width(24).height(24).fillColor(task.completed ?$r('app.color.success_color'):$r('app.color.text_secondary')).margin({ right:12})// 任务信息Column({ space:4}){Text(task.title).fontSize(16).fontColor($r('app.color.text_primary')).maxLines(2).textOverflow({ overflow: TextOverflow.Ellipsis }).decoration({ type: task.completed ? TextDecorationType.LineThrough : TextDecorationType.None })Text(`ID: ${task.id} | 用户: ${task.userId}`).fontSize(12).fontColor($r('app.color.text_secondary'))}.alignItems(HorizontalAlign.Start).layoutWeight(1)// 箭头图标Image($r('app.media.ic_arrow_right')).width(16).height(16).fillColor($r('app.color.text_secondary'))}.width('100%').padding(16).backgroundColor($r('app.color.card_background')).borderRadius(8).margin({ bottom:8}).onClick(()=>this.onTaskClick(task)).gesture(LongPressGesture({ repeat:false}).onAction(()=>{this.toggleTaskStatus(task);}))}/** * 构建页面UI */build(){Column(){// 标题栏Row(){Text('任务清单').fontSize(20).fontWeight(FontWeight.Bold).fontColor($r('app.color.text_primary'))}.width('100%').height(56).padding({ left:16, right:16}).backgroundColor($r('app.color.card_background'))// 内容区域if(this.loadState === LoadState.LOADING){this.LoadingBuilder()}elseif(this.loadState === LoadState.ERROR){this.ErrorBuilder()}elseif(this.taskList.length ===0){this.EmptyBuilder()}else{// 任务列表List({ space:0}){ForEach(this.taskList,(task: TaskItem, index:number)=>{ListItem(){this.TaskItemBuilder(task, index)}},(task: TaskItem)=> task.id.toString())}.width('100%').layoutWeight(1).padding({ left:16, right:16, top:8}).scrollBar(BarState.Auto).edgeEffect(EdgeEffect.Spring)}// 统计信息if(this.loadState === LoadState.SUCCESS&&this.taskList.length >0){Row(){Text(`共 ${this.taskList.length} 条任务`).fontSize(14).fontColor($r('app.color.text_secondary'))Blank()Text(`已完成: ${this.taskList.filter(t => t.completed).length}`).fontSize(14).fontColor($r('app.color.success_color'))}.width('100%').height(48).padding({ left:16, right:16}).backgroundColor($r('app.color.card_background'))}}.width('100%').height('100%').backgroundColor($r('app.color.background_color'))}}

6.2 样式配置类

// entry/src/main/ets/common/styles/AppStyles.ets/** * 应用样式配置 */exportclassAppStyles{// 间距staticreadonlySPACING={XS:4,SM:8,MD:12,LG:16,XL:20,XXL:24};// 字体大小staticreadonlyFONT_SIZE={XS:12,SM:14,MD:16,LG:18,XL:20,XXL:24};// 圆角staticreadonlyRADIUS={SM:4,MD:8,LG:12,XL:16,CIRCLE:999};// 阴影staticreadonlySHADOW={SM:{ radius:4, color:'#1A000000', offsetX:0, offsetY:2},MD:{ radius:8, color:'#1A000000', offsetX:0, offsetY:4},LG:{ radius:16, color:'#1A000000', offsetX:0, offsetY:8}};}

七、常见问题与解决方案

7.1 网络请求相关

问题1:网络请求失败提示权限不足

错误信息: Permission denial 

解决方案:检查module.json5中是否正确配置网络权限

"requestPermissions": [ { "name": "ohos.permission.INTERNET", "reason": "$string:internet_permission_reason", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } } ] 

问题2:HTTPS证书校验失败

解决方案:在开发阶段可临时忽略证书校验(生产环境不推荐)

httpRequest.request(url,{// 使用http协议仅用于开发测试// 生产环境必须使用https并正确配置证书})

7.2 UI渲染相关

问题3:列表数据更新后UI不刷新

解决方案:确保使用@State装饰状态变量,更新时触发刷新

// 错误做法this.taskList[index].completed =true;// 正确做法this.taskList.splice(index,1,{...task, completed:true});

问题4:ForEach渲染警告:需要唯一的key标识

解决方案:确保ForEach的第三个参数返回唯一标识

ForEach(this.taskList,(task: TaskItem)=>{ListItem(){...}},(task: TaskItem)=> task.id.toString())// 使用唯一ID作为key

7.3 资源引用相关

问题5:资源引用报错"Resource is not defined"

解决方案:使用$r()语法引用资源

// 错误写法Text('加载中')// 正确写法Text($r('app.string.loading_text'))

7.4 Git操作相关

问题6:推送时提示"remote rejected"

解决方案:

# 拉取远程最新代码git pull origin main --rebase# 解决冲突后推送git push origin main 

问题7:提交时报错"nothing to commit"

解决方案:检查文件状态

# 查看文件状态git status # 添加文件gitadd.# 提交git commit -m"feat: 添加任务列表功能"

八、测试与验证

8.1 模拟器运行

  1. 打开Device Manager
  2. 创建Phone模拟器(API 10+)
  3. 选择模拟器,点击运行按钮

8.2 功能验证清单

  • 应用启动正常,显示任务列表页面
  • 首次加载显示加载状态
  • 网络请求成功,显示任务列表
  • 点击任务项显示详情提示
  • 长按任务项切换完成状态
  • 下拉刷新功能正常
  • 错误状态显示正确,重试功能可用
  • 空数据状态显示正确
  • 统计信息正确显示

8.3 日志记录

// 添加日志标签constTAG='[TaskListPage]';// 使用console记录日志console.log(`${TAG} 加载数据`);console.error(`${TAG} 加载失败: ${error.message}`);console.warn(`${TAG} 数据为空`);

九、代码提交规范

9.1 提交信息格式

遵循 Conventional Commits 规范:

<type>(<scope>): <subject> <body> <footer> 

9.2 常用提交类型

类型说明示例
feat新功能feat(task): 添加任务列表功能
fix问题修复fix(network): 修复网络请求超时问题
docs文档更新docs(readme): 更新项目说明文档
style代码格式style(ui): 统一代码缩进格式
refactor重构refactor(service): 重构网络请求层
test测试test(api): 添加单元测试用例
chore构建/工具chore(deps): 更新依赖版本

9.3 提交示例

# 功能开发提交gitadd.git commit -m"feat(task): 实现任务列表数据加载与展示 - 添加网络请求封装类HttpUtil - 添加任务数据服务TaskService - 实现任务列表页面UI - 支持下拉刷新和状态切换"# 问题修复提交gitadd.git commit -m"fix(ui): 修复列表项点击事件无响应问题"# 文档更新提交gitadd README.md git commit -m"docs(readme): 更新项目运行环境说明"

十、进阶优化方向

10.1 数据持久化

// 使用Preferences存储本地数据import dataPreferences from'@ohos.data.preferences';exportclassLocalStorage{privatestatic preferences: dataPreferences.Preferences |null=null;staticasyncinit(context: Context):Promise<void>{this.preferences =await dataPreferences.getPreferences(context,'task_store');}staticasyncsaveTasks(tasks: TaskItem[]):Promise<void>{awaitthis.preferences?.put('tasks',JSON.stringify(tasks));awaitthis.preferences?.flush();}staticasyncgetTasks():Promise<TaskItem[]>{const data =awaitthis.preferences?.get('tasks','[]');returnJSON.parse(data asstring);}}

10.2 状态管理

// 使用简单的状态管理exportclassStore<T>{private state:T;private listeners:Array<(state:T)=>void>=[];constructor(initialState:T){this.state = initialState;}getState():T{returnthis.state;}setState(newState: Partial<T>):void{this.state ={...this.state,...newState };this.notify();}subscribe(listener:(state:T)=>void):()=>void{this.listeners.push(listener);return()=>{const index =this.listeners.indexOf(listener);this.listeners.splice(index,1);};}privatenotify():void{this.listeners.forEach(listener =>listener(this.state));}}

10.3 图片缓存

// 简单的图片缓存管理exportclassImageCache{privatestatic cache: Map<string, PixelMap>=newMap();staticasyncget(url:string):Promise<PixelMap |null>{if(this.cache.has(url)){returnthis.cache.get(url)!;}const imageSource = image.createImageSource(url);const pixelMap =await imageSource.createPixelMap();this.cache.set(url, pixelMap);return pixelMap;}staticclear():void{this.cache.clear();}}

十一、总结

本文通过一个完整的网络请求与数据列表示例,介绍了HarmonyOS应用开发的核心流程:

11.1 核心知识点回顾

  1. 工程结构:合理的目录结构提升代码可维护性
  2. 配置文件:module.json5、oh-package.json5等核心配置
  3. 网络请求:基于@ohos.net.http的封装与使用
  4. UI组件:List、ForEach等组件实现列表展示
  5. 状态管理:@State装饰器的响应式更新机制
  6. 资源管理:字符串、颜色等资源的统一管理

11.2 关键收获

  • 掌握鸿蒙应用的基本开发流程
  • 了解网络请求的标准封装方式
  • 熟悉列表组件的最佳实践
  • 学会常见问题的排查与解决

11.3 下一步学习建议

  1. 深入学习ArkTS语法和特性
  2. 掌握更多UI组件的使用方法
  3. 学习应用数据持久化方案
  4. 了解分布式开发相关特性
  5. 探索性能优化技巧

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.ZEEKLOG.net

参考资源:HarmonyOS官方文档OpenHarmony文档JSONPlaceholder测试接口

Read more

Flutter for OpenHarmony: Flutter 三方库 flutterfire_cli 自动化鸿蒙应用与 Firebase 云端的集成链路(工程自动化神器)

Flutter for OpenHarmony: Flutter 三方库 flutterfire_cli 自动化鸿蒙应用与 Firebase 云端的集成链路(工程自动化神器)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在进行 OpenHarmony 应用的出海开发时,Firebase 是必不可少的后端基础设施。然而,在鸿蒙工程中手动配置 Firebase 的各个平台配置文件(如 google-services.json 或 GoogleService-Info.plist)以及管理各个功能模块(Auth, Crashlytics, Analytics)的初始化代码,不仅繁琐且极其容易出错。 flutterfire_cli 是官方提供的自动化工具链。它能通过命令行交互的方式,自动为你的 Flutter 鸿蒙项目配置所有必要的文件,并生成跨平台一致的初始化 Dart 代码。它是实现鸿蒙-Firebase 体系“零配置”集成的关键。 一、自动化集成工作流模型 flutterfire_cli 取代了原本需要数小时的手动配置过程。 flutterfire configure (命令行) Firebase

By Ne0inhk
Ubuntu 24.04 换源教程:快速切换为阿里源

Ubuntu 24.04 换源教程:快速切换为阿里源

Ubuntu 24.04 LTS(代号 "Noble Numbat")已经正式发布,默认的软件源位于国外,国内用户在使用时可能会遇到下载速度慢、更新失败等问题。为了提高软件包的下载速度和稳定性,我们可以将默认的软件源更换为国内的阿里云镜像源。本文将详细介绍如何在 Ubuntu 24.04 中更换为阿里源。 一、为什么要换源? 1. 下载速度更快:国内镜像源通常位于国内服务器,访问速度更快。 2. 稳定性更高:避免因网络问题导致的下载失败或中断。 3. 减少延迟:国内源可以显著减少软件包下载和更新的延迟。 二、更换阿里源的步骤 方法一:命令行方式(推荐) 1. 保存并退出 按下 Ctrl + X,然后按 Y 确认保存,最后按 Enter 键退出编辑器。 更新软件包列表 执行以下命令更新软件包列表:

By Ne0inhk
分享个人制作的Openclaw 2026.3.7 Docker离线部署方案

分享个人制作的Openclaw 2026.3.7 Docker离线部署方案

分享个人制作的Openclaw 2026.3.7 Docker离线部署方案 文档编辑时间:2026-3-8 1、下载镜像 个人分享的镜像,保证无毒无木马,基于node:22-bookworm镜像制作。 网盘地址: https://pan.baidu.com/s/1RqyskudGPxCPdpxvCQ7mzQ?pwd=c1us 提取码: c1us 2、导入镜像 docker load --input openclaw-2026.3.7.images 3、修改配置 在linux服务器/home/openclaw/docker/default/目录下面创建一个.openclaw文件夹,在里面创建openclaw.json文件,当然这个目录你可以自己指定,内容如下: {"meta":{"

By Ne0inhk

Openclaw ubuntu 22.04部署,超详细,对接百炼模型(中文社区版)

一、安装要求 1、node版本必须>=22.0 node下载网址:https://nodejs.org/en/download 2、linux系统版本大于centos7,推荐用centos8或者ubuntu22或更高版本 3、提前准备好对接的AI平台的ApiKey秘钥,例如百炼,Kimi,MiniMax,openai等 4、安装openclaw的机器可访问公网 5、参考文档 官网:https://openclaw.ai/ 中文社区官网:https://clawd.org.cn/ 二、安装步骤 1、安装git sudo apt update && sudo apt install git -y git

By Ne0inhk