• Lv0
    粉丝0

积分2 / 贡献0

提问0答案被采纳0文章1

作者动态

    [其他] 6.开发流程:创建和使用第三方库、API 集成、应用开发.md

    Jinjy 显示全部楼层 发表于 5 天前
    ```
    # 开发流程:创建和使用第三方库、API 集成、应用开发

    ## 1. 三方库的创建与应用

    在上周的课程中,我们介绍了如何创建和使用三方库。从三方库的创建、查找、移植到发布,我们详细讨论了整个流程。希望大家能够参与到三方库的开发中,不仅能够提高开发效率,还能贡献到开源社区。

    ### 1.1 三方库的创建与实现

    - **创建静态库**:在开发过程中,首先需要创建一个静态库,这是整个三方库的核心部分。在库中实现具体的功能(如房贷计算工具)。
    - **接口暴露**:实现功能后,需通过适当的接口暴露这些功能,使得其他模块能够调用。
    - **开发解耦**:通过将功能模块解耦,方便后续的开发和维护。

    ### 1.2 三方库的发布方式

    - **本地路径引入**:可以选择将库存放在本地,通过相对路径引用进行使用。
    - **发布到 OHPM 仓库**:将库发布到 OHPM 仓库,其他开发者通过 `OHPM install` 命令来安装和使用。

    ## 2. 开源和社区参与

    ### 2.1 开源项目的重要性

    参与开源项目不仅能够提升自己的开发技能,还能通过分享代码和经验,让更多开发者受益。无论是发布功能库,还是分享使用教程,都有助于增强开发者社区的活力。

    - **参与共建**:通过贡献代码和文档,能够和其他开发者一起进步,解决实际问题。
    - **知识分享**:把开发经验和技术总结分享出来,能帮助他人,同时也能够为自己积累更高的声誉。

    ## 3. 开发实战:汇率计算应用

    今天我们将演示一个简单的应用开发过程,通过创建一个汇率计算应用,帮助大家更好地理解如何在实际项目中应用三方库。

    ### 3.1 创建项目

    1. **选择模板**:选择一个空模板开始创建项目。
    2. **输入项目名称**:比如输入“汇率计算”作为项目名称。
    3. **设置目标 API 版本**:确保项目能够兼容目标 API 版本(例如从 API 9 升级到 API 12)。

    ![20241128194803](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128194803.png)

    ### 3.2 集成第三方 API

    - **汇率计算接口**:我们通过一个免费的汇率计算 API 来获取汇率数据。你可以通过接口地址和请求参数来获取转换后的汇率数据。

    https://www.alapi.cn


    ```text
    API 地址:<API地址>
    请求方式:GET / POST
    请求参数:token, money, from, to
    返回参数:汇率数据等
    ```

    ![20241128195037](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128195037.png)

    接口地址:https://v2.alapi.cn/api/exchange

    ![20241128195149](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128195149.png)

    请求方法: [ "GET", "POST" ]

    请求参数:

    | 参数名 | 类型   | 必填 | 描述           |
    | ------ | ------ | ---- | -------------- |
    | token  | string | 是   | 请求唯一凭证   |
    | money  | number | 是   | 需要转换的金额 |
    | from   | string | 是   | 需要转换的货币 |
    | to     | string | 是   | 转换后的货币   |

    ### 3.3 实现功能

    1. **请求接口**:通过 HTTP 请求获取汇率数据。
    2. **处理数据**:解析返回的 JSON 数据,并将其显示在界面上。

    ### 3.4 HTTP 请求实现

    在项目中,使用 `HTTP` 请求来获取汇率数据。这里我们使用 `GET` 或 `POST` 请求方式,并传递相关参数。

    [HTTP数据请求](https://developer.huawei.com/consumer/cn/doc/atomic-guides-V5/atomic-http-request-V5)

    ![20241128200007](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128200007.png)

    ![20241128200104](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128200104.png)

    request接口开发步骤
    1.从@ohos.net.http中导入http命名空间。

    ```javascript
    // 引入包名
    import http from '@ohos.net.http';
    import { BusinessError } from '@ohos.base';
    ```

    2.调用createHttp()方法,创建一个HttpRequest对象。

    ```javascript
    // 每一个httpRequest对应一个HTTP请求任务,不可复用
    let httpRequest = http.createHttp();
    ```

    3.调用该对象的on()方法,订阅http响应头事件,此接口会比request请求先返回。可以根据业务需要订阅此消息。

    ```javascript
    // 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
    // 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。
    httpRequest.on('headersReceive', (header) => {
      console.info('header: ' + JSON.stringify(header));
    });
    ```

    ![20241128200942](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128200942.png)

    4.调用该对象的request()方法,传入http请求的url地址和可选参数,发起网络请求。

    ```javascript
    httpRequest.request(
      // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
      "EXAMPLE_URL",
      {
        method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
        // 开发者根据自身业务需要添加header字段
        header: {
          'Content-Type': 'application/json'
        },
        // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定
        extraData: "data to send",
        expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
        usingCache: true, // 可选,默认为true
        priority: 1, // 可选,默认为1
        connectTimeout: 60000, // 可选,默认为60000ms
        readTimeout: 60000, // 可选,默认为60000ms
        usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
        usingProxy: false, // 可选,默认不使用网络代理,自API 10开始支持该属性
      }, (err: BusinessError, data: http.HttpResponse) => {
        if (!err) {
          // data.result为HTTP响应内容,可根据业务需要进行解析
          console.info('Result:' + JSON.stringify(data.result));
          console.info('code:' + JSON.stringify(data.responseCode));
          // data.header为HTTP响应头,可根据业务需要进行解析
          console.info('header:' + JSON.stringify(data.header));
          console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
          // 当该请求使用完毕时,调用destroy方法主动销毁
          httpRequest.destroy();
        } else {
          console.error('error:' + JSON.stringify(err));
          // 取消订阅HTTP响应头事件
          httpRequest.off('headersReceive');
          // 当该请求使用完毕时,调用destroy方法主动销毁
          httpRequest.destroy();
        }
      }
    );
    ```

    将复制的代码改造,输入刚才的接口
    ![20241128201437](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128201437.png)

    使用 post 请求,可以在extraData里面去输入额外的一个参数。可以去输入这 4 个参数,token ,money ,from ,to

    ![20241128201917](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128201917.png)

    示例:

    登录领取token
    ![20241128202150](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128202150.png)

    ![20241128202416](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128202416.png)

    输入参数:

    ![20241128203051](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128203051.png)

    5.按照实际业务需要,解析返回结果。

    ⚠️添加网络权限

    ![20241128203539](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128203539.png)

    以post 为例,测试一下,看返回的结果

    ![20241128204042](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128204042.png)

    如何解析?
    有对应的一个工具,或者也可以自己去手写

    在etc下面,新建一个model的一个文件夹,去专门处理我们的一个定义好的这个模型,模型里面我们就可以去处理我们的对应的一个数据。

    新建一个ArkTS File文件exchange

    ![20241128204535](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128204535.png)

    ![20241128204653](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128204653.png)

    可以使用Json2ets,去解析我们的一个json数据,把数据定义好,然后去解析。
    ![20241128220654](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128220654.png)

    [Jsonets插件下载地址](https://plugins.jetbrains.com/plugin/24930-jsonformat)

    ![20241128221208](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128221208.png)

    去生成一个 class 的一个类,格式化

    ![20241128221432](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128221432.png)

    ![20241128221507](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128221507.png)

    首次加载的时候,用aboutToAppear() 的一个这样的一个生命周期,然后去执行一次的 get data。

    ![20241128222837](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128222837.png)

    现在打个断点去调试啊。所以这里面大家要注意到,就是我们在请这个刚开始做开发的时候,我们可以点击这边的一个 debug 的一个按钮,方便大家去做调试,我们看能不能跑进去。跑进来以后我们看一下数据是不是拿到了,然后拿到的其实就是刚才我们在测试的时候的这样的一个数据,我们说明这个数据是正确的。

    ![20241128223159](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128223159.png)

    首先,需要将其转换为字符串类型。这是因为直接操作会导致报错,而报错的原因是缺少必要的模块导入。至于如何完成模块导入,有以下几种方式:

    1. 可以直接在开发工具中点击提示选项,自动完成导入。
    2. 如果工具未能正确识别模块,还可以手动进行导入操作。例如,通过 import 语句明确导入所需的模块。

    这两种方式都能够有效解决问题,确保代码正常运行。
    ![20241128223629](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128223629.png)

    ![20241128224248](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128224248.png)

    ![20241128224226](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128224226.png)

    现在,我们需要全局定义一个变量,并实现数据刷新的功能。例如,可以创建一个 set 方法,专门用于更新数据。接着,定义一个类用于数据的观测和管理,以便更加高效地处理和维护相关的状态。

    ![20241128224545](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128224545.png)

    Index.est完整代码

    ```typescript
    import http from '@ohos.net.http';
    import { BusinessError } from '@ohos.base';
    import { exchange, ExchangeData } from '../model/exchange';

    @Entry
    @Component
    struct Index {
      @State value: number = 0;
      @State exchangeData:ExchangeData=new ExchangeData()
      aboutToAppear(): void {
        this.getData(1)
      }
      getData(mony:number){
        // 每一个httpRequest对应一个HTTP请求任务,不可复用
        let httpRequest = http.createHttp();
        // 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
        // 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。
        httpRequest.on('headersReceive', (header) => {
          console.info('header: ' + JSON.stringify(header));
        });
        httpRequest.request(
          // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
          "https://v2.alapi.cn/api/exchange",
          {
            method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
            // 开发者根据自身业务需要添加header字段
            header: {
              'Content-Type': 'application/json'
            },
            // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定
            extraData: {
              "token":"qlVquQZPYSeaCi6u",
              "money": mony,
              "form":"USD",
              "to":"CNY"
            },
            expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
            usingCache: true, // 可选,默认为true
            priority: 1, // 可选,默认为1
            connectTimeout: 60000, // 可选,默认为60000ms
            readTimeout: 60000, // 可选,默认为60000ms
            usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
            usingProxy: false, // 可选,默认不使用网络代理,自API 10开始支持该属性
          }, (err: BusinessError, data: http.HttpResponse) => {
          if (!err) {
            let exchange:exchange=JSON.parse(data.result.toString())
            this.exchangeData = exchange.data!

            // data.result为HTTP响应内容,可根据业务需要进行解析
            console.info('Result:' + JSON.stringify(data.result));
            console.info('code:' + JSON.stringify(data.responseCode));
            // data.header为HTTP响应头,可根据业务需要进行解析
            console.info('header:' + JSON.stringify(data.header));
            console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
            // 当该请求使用完毕时,调用destroy方法主动销毁
            httpRequest.destroy();
          } else {
            console.error('error:' + JSON.stringify(err));
            // 取消订阅HTTP响应头事件
            httpRequest.off('headersReceive');
            // 当该请求使用完毕时,调用destroy方法主动销毁
            httpRequest.destroy();
          }
        }
        );
      }
      build() {
        Column() {
          TextInput({
            placeholder:"请输入兑换的金额",
            text:this.value.toString()
          }).type(InputType.Number)
            .onChange((e:string)=>{
              this.value = parseInt(e)
              this.getData(parseInt(e))
            })
          Text(this.exchangeData.exchange
          ?.toString())
        }
        .height('100%')
        .width('100%')
      }
    }
    ```

    ![20241128231304](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128231304.png)

    ![20241128231616](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128231616.png)

    ![20241128231807](https://cdn.jsdelivr.net/gh/jinjy-03/gallery@main/blogs/pictures/20241128231807.png)

    6.调用该对象的off()方法,取消订阅http响应头事件。
    7.当该请求使用完毕时,调用destroy()方法主动销毁。

    ## 4. 重要注意事项

    - **网络权限**:开发 Android 应用时,要确保在 `AndroidManifest.xml` 中配置了网络权限。
    - **调试和测试**:在模拟器或真实设备中调试时,务必关注请求的权限和数据的正确性。

    ### 4.1 添加网络权限

    在 `AndroidManifest.xml` 文件中添加以下权限:

    ```xml
    <uses-permission android:name="android.permission.INTERNET"/>
    ```

    ```

    ```

    ©著作权归作者所有,转载或内容合作请联系作者

    您尚未登录,无法参与评论,登录后可以:
    参与开源共建问题交流
    认同或收藏高质量问答
    获取积分成为开源共建先驱

    Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

    返回顶部