HarmonyOS 鸿蒙Next 线上Codelabs系列挑战赛第二期 天气预报应用 · 封装本地库并使用三方库制作

HarmonyOS 鸿蒙Next 线上Codelabs系列挑战赛第二期 天气预报应用 · 封装本地库并使用三方库制作

ArkStageWeatherDemo

项目地址
项目已经上传到Gitee,欢迎各位开发者阅读及批判。
https://gitee.com/laomao1997/ark-stage-weather-demo

介绍 Intro

基于鸿蒙ArkTS语言Stage模型构建的天气应用Demo。使用了Lottie动画库。
Build the app based on the OpenHarmony ArkTS language and the Stage model.
Achieve the basic functions of a weather application.

软件架构 Software Achitechture

项目文件目录如下所示:

ArkStageWeatherDemo
├─entry     // 程序入口
│  └─src
│      ├─main
│      │  ├─ets
│      │  │  ├─common
│      │  │  │  ├─bean      // 项目相关 bean 对象文件夹
│      │  │  │  ├─constants // 常量文件夹
│      │  │  │  ├─lottie    // Lottie 动画 JSON 文件夹
│      │  │  │  └─utils     // 工具类文件夹
│      │  │  │      └─log   // 日志工具文件夹
│      │  │  ├─entryability // 程序入口
│      │  │  ├─pages        // 相关页面
│      │  │  ├─view         // 相关视图
│      │  │  └─viewmodel    // 相关viewmodel
│      │  └─resources
│      │      └─base
│      │          ├─element
│      │          ├─media
│      │          └─profile
│      └─ohosTest
│
└─MyWeather // 本地天气库 - MyWeather
   └─src
       └─main
           ├─ets
           │  ├─bean      // 天气相关 bean 对象文件夹
           │  ├─client    // 天气请求客户端类文件夹
           │  └─constants // 常量文件夹
           └─resources
               └─base
                   └─element

可以发现程序主要由两部分组成:

  • entry - 作为程序的主入口,程序的页面及相关逻辑都在此 module 下;
  • MyWeather - 天气请求本地库,基于“和风天气”封装了天气请求,使得其他module可以通过调用该模块对外提供的接口实现天气相关信息获取。

此外,程序还使用到了@ohos/lottieETS外部库,用于播放天气动画。

本地库 MyWeather 封装

为了便于调用天气接口,实现适当的解耦,讲天气访问功能进行了抽取,封装成MyWeather本地库。截图如下:

核心代码如下:

实况天气请求

/**
 * NowWeatherClient.ets
 * 实况天气请求
 */

import http from '@ohos.net.http';
import { NowWeatherBean } from "../bean/NowWeatherBean";
import { MyWeatherConstants } from "../constants/Constants"

export class NowWeatherClient {

  /**
   * 天气请求 KEY
   */
  private api_key: string = "";

  /**
   * 构造方法
   *
   * @param apiKey 天气请求 KEY
   */
  constructor(apiKey: string) {
    this.api_key = apiKey;
  }

  /**
   * 异步获取实时天气数据
   *
   * @param cityId   城市 ID,需传入所要查看天气城市的 ID
   * @param callback 请求回调,将回调一个 NowWeatherBean 对象
   */
  public getNowWeatherData(cityId: string, callback: (bean: NowWeatherBean) => any) {
    let bean = null;
    if (cityId.length == 0) {
      callback(bean)
    }
    // 实例化 httpRequest 对象
    let httpRequest = http.createHttp();
    // 订阅 http 响应头
    httpRequest.on('headersReceive', (header) => {
      console.info('ZJH: header: ' + JSON.stringify(header));
    });
    // 发起 http 请求
    httpRequest.request(
    this.buildRequestUrl(cityId),
      (err, data) => {
        if (!err) {
          console.info('ZJH: Result:' + data.result);
          console.info('ZJH: Result type: ' + typeof data.result);
          console.info('ZJH: code:' + data.responseCode);
          // 解析响应,获取 NowWeatherBean 对象
          bean = this.parseNowWeather(data.result as string);
          httpRequest.destroy();
          // 解析成功,回调 NowWeatherBean 对象到外部
          callback(bean);
        } else {
          console.info('ZJH: error:' + JSON.stringify(err));
          httpRequest.destroy();
          callback(bean);
        }
      }
    );
  }

  private buildRequestUrl(cityId: string): string {
    let finalUrl = MyWeatherConstants.URL_NOW_WEATHER + "?key=" + this.api_key + "&location=" + cityId;
    return finalUrl;
  }

  private parseNowWeather(nowWeatherData: string): NowWeatherBean {
    console.info('ZJH: parseNowWeather: nowWeatherData:' + nowWeatherData);
    let bean: NowWeatherBean = JSON.parse(nowWeatherData);
    console.info('ZJH: parseNowWeather: nowWeatherData2:' + bean.now.text);
    console.info('ZJH: parseNowWeather: nowWeatherData2:' + bean.now.temp);
    console.info('ZJH: parseNowWeather: nowWeatherData2:' + bean.now.windSpeed);
    return bean;
  }
}

三日天气预报请求

/**
 * ThreeDayWeatherClient.ets
 * 三日天气预报请求
 */

import http from '@ohos.net.http';
import { ThreeDayWeatherBean } from "../bean/ThreeDayWeatherBean";
import { MyWeatherConstants } from "../constants/Constants"

export class ThreeDayWeatherClient {

  /**
   * 天气请求 KEY
   */
  private api_key: string = "";

  /**
   * 构造方法
   *
   * @param apiKey 天气请求 KEY
   */
  constructor(apiKey: string) {
    this.api_key = apiKey;
  }

  /**
   * 异步获取实时天气数据
   *
   * @param cityId   城市 ID,需传入所要查看天气城市的 ID
   * @param callback 请求回调,将回调一个 NowWeatherBean 对象
   */
  public getThreeDayWeatherData(cityId: string, callback: (bean: ThreeDayWeatherBean) => any) {
    let bean = null;
    if (cityId.length == 0) {
      callback(bean)
    }
    // 实例化 httpRequest 对象
    let httpRequest = http.createHttp();
    // 订阅 http 响应头
    httpRequest.on('headersReceive', (header) => {
      console.info('ZJH: header: ' + JSON.stringify(header));
    });
    // 发起 http 请求
    httpRequest.request(
    this.buildRequestUrl(cityId),
      (err, data) => {
        if (!err) {
          console.info('ZJH: Result:' + data.result);
          console.info('ZJH: Result type: ' + typeof data.result);
          console.info('ZJH: code:' + data.responseCode);
          // 解析响应,获取 NowWeatherBean 对象
          bean = this.parseThreeDayWeather(data.result as string);
          httpRequest.destroy();
          // 解析成功,回调 NowWeatherBean 对象到外部
          callback(bean);
        } else {
          console.info('ZJH: error:' + JSON.stringify(err));
          httpRequest.destroy();
          callback(bean);
        }
      }
    );
  }

  private buildRequestUrl(cityId: string): string {
    let finalUrl = MyWeatherConstants.URL_THREE_DAY_WEATHER + "?key=" + this.api_key + "&location=" + cityId;
    return finalUrl;
  }

  private parseThreeDayWeather(threeDayWeatherData: string): ThreeDayWeatherBean {
    console.info('ZJH: parseThreeDayWeather: threeDayWeatherData:' + threeDayWeatherData);
    let bean: ThreeDayWeatherBean = JSON.parse(threeDayWeatherData);
    return bean;
  }
}

天气数据统一单例入口类

/**
 * MyWeather.ets
 * 模块入口,单例,外界通过调用该类可以进行各种天气信息的访问
 */

import { NowWeatherBean } from "./bean/NowWeatherBean";
import { NowWeatherClient } from "./client/NowWeatherClient";
import { ThreeDayWeatherBean } from "./bean/ThreeDayWeatherBean";
import { ThreeDayWeatherClient } from "./client/ThreeDayWeatherClient";

export class MyWeather {

  /**
   * 单例模式私有实例
   */
  private static instance: MyWeather;

  /**
   * 天气请求 KEY
   */
  private api_key: string = "";

  /**
   * 私有构造方法
   */
  private constructor() {
  }

  /**
   * 获取当前类实例,懒加载
   */
  public static getInstance() {
    if (this.instance == null) {
      this.instance = new MyWeather();
    }
    return this.instance;
  }

  /**
   * 初始化当前 Client,目前作用是为 Client 设置请求 API KEY
   *
   * @param apiKey 天气请求 API KEY
   */
  public init(apiKey: string) {
    this.api_key = apiKey;
  }

  /**
   * 异步获取实时天气数据
   *
   * @param cityId   城市 ID,需传入所要查看天气城市的 ID
   * @param callback 请求回调,将回调一个 NowWeatherBean 对象
   */
  public getNowWeatherData(cityId: string, callback: (bean: NowWeatherBean) => any) {
    let nowWeatherClient = new NowWeatherClient(this.api_key);
    nowWeatherClient.getNowWeatherData(cityId, callback);
  }

  /**
   * 异步获取三日天气预报数据
   *
   * @param cityId   城市 ID,需传入所要查看天气城市的 ID
   * @param callback 请求回调,将回调一个 NowWeatherBean 对象
   */
  public get3DayWeatherData(cityId: string, callback: (bean: ThreeDayWeatherBean) => any) {
    let threeDayWeatherClient = new ThreeDayWeatherClient(this.api_key);
    threeDayWeatherClient.getThreeDayWeatherData(cityId, callback);
  }
}

后续优化

目前的效果只是一个简单的最小功能实现,只是能够以较为简陋的方式展示固定5个城市的实况天气和3天天气预报,无法允许用户自行选择城市,也没有实现实时刷新和缓存等功能,后续考虑从以下几个方面继续优化:

  1. 增加城市列表添加和删除城市功能;
  2. 增加缓存功能,缓存天气数据以降低对服务器的压力;
  3. 增加定时刷新功能,确保天气的相对准确性;
  4. 增加下拉刷新功能,允许用户手动刷新当前城市天气。

更多关于HarmonyOS 鸿蒙Next 线上Codelabs系列挑战赛第二期 天气预报应用 · 封装本地库并使用三方库制作的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next 线上Codelabs系列挑战赛第二期 天气预报应用 · 封装本地库并使用三方库制作的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next系统中,封装本地库并使用三方库制作天气预报应用,主要涉及以下几个步骤:

  1. 封装本地库

    • 使用鸿蒙系统的ArkCompiler编译工具,将本地代码(如C++、Dart等,但不包括Java和C语言,按题目要求)封装成鸿蒙可识别的库文件。
    • 创建一个鸿蒙模块,用于管理本地库的功能接口,确保这些接口在鸿蒙应用中可调用。
  2. 使用三方库

    • 在鸿蒙项目的build.gradle或对应配置文件中,添加三方库的依赖项。确保所选的三方库已适配鸿蒙系统。
    • 根据三方库的文档,调用其提供的API来实现天气预报功能。这可能包括获取天气数据、解析数据以及展示数据等。
  3. 整合应用

    • 将封装好的本地库和三方库的功能整合到鸿蒙应用中,确保应用能够正确调用这些库提供的功能。
    • 进行充分的测试,确保应用在各种场景下都能稳定运行。

如果问题依旧没法解决请联系官网客服,官网地址是: https://www.itying.com/category-93-b0.html

回到顶部