HarmonyOS NEXT应用开发(一、打造最好用的网络通信模块组件)

news/2024/10/5 15:51:16 标签: harmonyos, 华为

随着HarmonyOS NEXT 的发布,越来越多的开发者开始关注如何在这个新平台上高效地进行应用开发。其中网络通信模块的封装尤为关键。纵观HarmonyOS的众多三方网络库及封装,竟没有一个简单好用的。虽然有个axios的鸿蒙版,但有点儿重了也不是很好用。本篇博文将介绍如何将uniapp中的luch-request网络库移植到HarmonyOS中,从而实现更简单、高效的HTTP网络通信。

为什么选择luch-request?

在HarmonyOS中,原始的ohos.net.http接口虽然功能强大,但在实际使用中却存在一些复杂性和局限性。这使得开发者在进行网络请求时需要写更多的代码,而且处理错误、配置请求等操作也较为繁琐。而uniapp中的luch-request,使用起来特别的简单好用,且比axios更简单和轻量级,功能一点也不弱。

相较而言,luch-request网络库的优点:

  1. 简洁易用:提供了易于理解的API接口,开发者可以通过简单的调用来实现复杂的网络请求。
  2. Promise支持:内置了Promise支持,方便与异步编程结合,提升代码的可读性和维护性。
  3. 请求拦截器和响应拦截器:可以方便地添加请求和响应的拦截器,用于统一处理请求头、参数和错误处理。
  4. 自动化的JSON数据解析:返回的数据会自动解析成JSON格式,省去了手动解析的步骤。
  5. 支持多种请求方式:GET、POST、PUT、DELETE等多种请求方式都能轻松实现。

luch-request网络库地址:GitHub - lei-mu/luch-request: luch-request 是一个基于Promise 开发的uni-app跨平台、项目级别的请求库,它有更小的体积,易用的api,方便简单的自定义能力。

官网介绍: 

luch-request

移植步骤

下面,我们将详细介绍如何将unIapp平台下的luch-request网络库移植到HarmonyOS中。

步骤一:准备环境

首先,你需要在HarmonyOS项目中引入luch-request库。我已经移植好了,发布在了Openharmony的三方库中。

移植后的gitee地址:yyz116/h_request

发布到三库库的地址:OpenHarmony三方库中心仓 

注:当前该三方库1.0.1版本正在审核中。可以从gitee项目中下载源码体验,内涵单元测试及demo。

可以这样引入使用:

ohpm  install @yyz116/h_request

import Request, { HttpRequestConfig, HttpResponse } from '@yyz116/h_request'

步骤二:封装请求模块

在你的HarmonyOS项目中创建一个新的网络请求模块,例如request.js,并在其中引入luch-request库。你需要对库进行小幅修改,以确保其与HarmonyOS环境兼容。

import Request, { HttpRequestConfig, HttpResponse } from '@yyz116/h_request'

const httpRequest = new Request();

httpRequest.setConfig((config) => {
    // Set base config
    config.baseURL = "https://your.api.url"; // 替换为你的API地址
    return config;
});

httpRequest.interceptors.request.use((config) => {
    // 可以在这里添加请求拦截器
    return config;
}, (error) => {
    return Promise.reject(error);
});

httpRequest.interceptors.response.use((response) => {
    // 可以在这里添加响应拦截器
    return response.data;
}, (error) => {
    return Promise.reject(error);
});

export default httpRequest;

步骤三:使用网络请求模块

在你的应用中,你可以通过引入request.js来进行网络请求。

import httpRequest from './request';

// 示例 GET 请求
httpRequest.get('/endpoint')
    .then(data => {
        console.log("获取数据成功:", data);
    })
    .catch(error => {
        console.error("请求失败:", error);
    });

// 示例 POST 请求
httpRequest.post('/endpoint', { key: 'value' })
    .then(data => {
        console.log("数据提交成功:", data);
    })
    .catch(error => {
        console.error("请求失败:", error);
    });

使用举例

// 发送post请求
http.post('api/v1/soonmovie', {start:0,count:1}).then((res:HttpResponse<Result>) => {
              hilog.debug(0x0000,"request",res.data.message)
              hilog.debug(0x0000,"request","res.data.code:%{public}d",res.data.code)
            }).catch((err:HttpResponse<Error>) => {
              hilog.debug(0x0000,"request","err.data.code:%d",err.data.code)
              hilog.debug(0x0000,"request",err.data.message)
            });

// 发送get请求,带参数
http.get('api/v1/musicsearchlrc', {params:{id:"543656129",kind:"wy"}}).then((res:HttpResponse<Result>) => {
              hilog.debug(0x0000,"request",res.data.message)
              hilog.debug(0x0000,"request","res.data.code:%{public}d",res.data.code)
            }).catch((err:HttpResponse<Error>) => {
              hilog.debug(0x0000,"request","err.data.code:%d",err.data.code)
              hilog.debug(0x0000,"request",err.data.message)
            });
          })

可以看到,接口使用变得如此简单。 且可以增加拦截器(建议把拦截器封装到单独的一个模块文件里,以下示例仅为示例utils/request.js):

 export const setRequestConfig = () => {

            http.setConfig((config:HttpRequestConfig) => {
              config.baseURL = "http://175.178.126.10:8000/";
              return config;
            });
            // 请求拦截
            http.interceptors.request.use(
              (config) => {
                hilog.debug(0x0000,"request",'请求拦截')
                return config
              },
              (error) => {
                return Promise.reject(error)
              }
            )
            // 响应拦截
            http.interceptors.response.use(
              (response:HttpResponse) => {
                hilog.debug(0x0000,"request",'响应拦截')
                if (response.data.code == 401) {
                  // 提示重新登录
                  console.log('请登录')
                  setTimeout(() => {
                    console.log('请请登录')
                  }, 1000);
                }
                return response
              },
              (error) => {
                return Promise.reject(error)
              }
            )

}

接口使用变得清晰明了,如下api封装模块user.js: 

import { setRequestConfig } from '@/utils/request.js';

// 调用setRequestConfig函数进行请求配置
setRequestConfig();
const http = uni.$u.http
// 发起登录请求
export const requestLogin = (data) => http.post('/wx-api/login', data);
//请求验证码  /wx-api/validcode   get   参数:{"phone":"xxx"}
export const  requestVerificationCode = (params = {}) => http.get(`/wx-api/validcode`, params)
//发起注册请求   /wx-api/register   post   
/*
参数:{"code": "xxx","phone": "xxx","verifyCode": "xxx","nickname": "xxx","avatarUrl": "xxx","gender":"0"}
*/
export const requestRegister = (data)=>http.post('/wx-api/register',data)
//获取个人中心信息   /wx-api/me/info   get
export const requestUserInfo = () => http.get('/wx-api/me/info')
//修改个人昵称  /wx-api/update/nickname post  参数:newNickname
export const requestNickname = (data)=>http.post('/wx-api/update/nickname',data)

完整示例

import Request, { HttpRequestConfig, HttpResponse } from '@yyz116/h_request'
import { hilog } from '@kit.PerformanceAnalysisKit';

interface Movie{
  id:string;
  cover:string;
  title:string;
  gener:string;
  rate:number;
}
interface Result{
  code:number;
  message:string;
  data:Array<Movie>;
  count:number;
  start:number;
  total:number;
  title:string;

}
interface Error{
  code:number;
  message:string;
  data:Array<Movie>;
  count:number;
  start:number;
  total:number;
  title:string;
}


@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        Button('test1').width(300).margin({ top: 20 })
          .onClick(() => {
            // 需要执行的操作
            const http = new Request();
            http.setConfig((config:HttpRequestConfig) => {
              config.baseURL = "http://175.178.126.10:8000/";
              return config;
            });
            // 请求拦截
            http.interceptors.request.use(
              (config) => {
                hilog.debug(0x0000,"request",'请求拦截')
                return config
              },
              (error) => {
                return Promise.reject(error)
              }
            )
            // 响应拦截
            http.interceptors.response.use(
              (response:HttpResponse) => {
                hilog.debug(0x0000,"request",'响应拦截')
                if (response.data.code == 401) {
                  // 提示重新登录
                  console.log('请登录')
                  setTimeout(() => {
                    console.log('请请登录')
                  }, 1000);
                }
                return response
              },
              (error) => {
                return Promise.reject(error)
              }
            )

            http.post('api/v1/soonmovie', {start:0,count:1}).then((res:HttpResponse<Result>) => {
              hilog.debug(0x0000,"request",res.data.message)
              hilog.debug(0x0000,"request","res.data.code:%{public}d",res.data.code)
            }).catch((err:HttpResponse<Error>) => {
              hilog.debug(0x0000,"request","err.data.code:%d",err.data.code)
              hilog.debug(0x0000,"request",err.data.message)
            });

            http.get('api/v1/musicsearchlrc', {params:{id:"543656129",kind:"wy"}}).then((res:HttpResponse<Result>) => {
              hilog.debug(0x0000,"request",res.data.message)
              hilog.debug(0x0000,"request","res.data.code:%{public}d",res.data.code)
            }).catch((err:HttpResponse<Error>) => {
              hilog.debug(0x0000,"request","err.data.code:%d",err.data.code)
              hilog.debug(0x0000,"request",err.data.message)
            });
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

总结

通过将luch-request网络库移植到HarmonyOS,我们大大简化了网络请求的过程。开发者可以享受到更加清晰、简洁的API,同时也提升了开发效率。如果你正在开发HarmonyOS应用,不妨尝试一下这个网络通信模块封装,让你的开发过程更加顺畅。希望本文对你有所帮助,欢迎交流与分享经验!

写在最后

最后,推荐下笔者的业余开源app影视项目“爱影家”,推荐分享给与我一样喜欢观影的朋友。

开源地址:爱影家app开源项目介绍及源码

https://gitee.com/yyz116/imovie

其他资源

luch-request

yyz116/h_request

OpenAtom OpenHarmony


http://www.niftyadmin.cn/n/5691025.html

相关文章

【Qt】控件概述(3)—— 显示类控件

显示类控件 1. QLabel——标签1.1 setPixmap设置图片1.2 setAlignment设置文本对齐方式1.3 setWordWrap设置自动换行1.4 setIndent设置缩进1.5 setMargin设置边距1.6 body 2. QLCDNumber2.1 使用QTimer实现一个倒计时效果2.2 使用循环的方式实现倒计时 3. QProgressBar——进度…

重学SpringBoot3-集成Redis(一)

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;一&#xff09; 1. 项目初始化2. 配置 Redis3. 配置 Redis 序列化4. 操作 Redis 工具类5. 编写 REST 控制器6. 测试 API7. 总结 随…

角色动画——RootMotion全解

1. Unity(2022)的应用 由Animtor组件控制 在Animation Clip下可进行详细设置 ​ 官方文档的介绍(Animation选项卡 - Unity 手册) 上述动画类型在Rag选项卡中设置: Rig 选项卡上的设置定义了 Unity 如何将变形体映射到导入模型中的网格&#xff0c;以便能够将其动画化。 对于人…

Fastjson反序列化

Fastjson反序列化一共有三条利用链 TempLatesImpl&#xff1a;实战中不适用JdbcRowSetImpl&#xff1a;实际运用中较为广泛BasicDataSource&#xff08;BCEL&#xff09; 反序列化核心 反序列化是通过字符串或字节流&#xff0c;利用Java的反射机制重构一个对象。主要有两种…

非机动车检测数据集 4类 5500张 电动三轮自行车 voc yolo

非机动车检测数据集 4类 5500张 电动三轮自行车 voc yolo 非机动车检测数据集介绍 数据集名称 非机动车检测数据集 (Non-Motorized Vehicle Detection Dataset) 数据集概述 该数据集专为训练和评估基于YOLO系列目标检测模型&#xff08;包括YOLOv5、YOLOv6、YOLOv7等&#x…

【C++算法】9.双指针_四数之和

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 18.四数之和 题目描述&#xff1a; 解法 解法一&#xff1a;排序暴力枚举利用set去重 解法二&#xff1a;排序双指针 从左往右依次固定一个数a在a后面的区间里&#x…

mybatis如何与spring的结合

1.前言 在现在的java项目开发中&#xff0c;MyBatis和Spring是两个非常流行的框架。MyBatis是一个优秀的持久层框架&#xff0c;它支持定制化SQL、存储过程以及高级映射。而Spring则是一个广泛使用的开源框架&#xff0c;用于构建企业级应用程序。将这两个框架整合在一起&…

Spring Boot大学生就业招聘系统的设计与优化

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…