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天天气预报,无法允许用户自行选择城市,也没有实现实时刷新和缓存等功能,后续考虑从以下几个方面继续优化:
- 增加城市列表添加和删除城市功能;
- 增加缓存功能,缓存天气数据以降低对服务器的压力;
- 增加定时刷新功能,确保天气的相对准确性;
- 增加下拉刷新功能,允许用户手动刷新当前城市天气。
更多关于HarmonyOS 鸿蒙Next 线上Codelabs系列挑战赛第二期 天气预报应用 · 封装本地库并使用三方库制作的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next 线上Codelabs系列挑战赛第二期 天气预报应用 · 封装本地库并使用三方库制作的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next系统中,封装本地库并使用三方库制作天气预报应用,主要涉及以下几个步骤:
-
封装本地库:
- 使用鸿蒙系统的ArkCompiler编译工具,将本地代码(如C++、Dart等,但不包括Java和C语言,按题目要求)封装成鸿蒙可识别的库文件。
- 创建一个鸿蒙模块,用于管理本地库的功能接口,确保这些接口在鸿蒙应用中可调用。
-
使用三方库:
- 在鸿蒙项目的build.gradle或对应配置文件中,添加三方库的依赖项。确保所选的三方库已适配鸿蒙系统。
- 根据三方库的文档,调用其提供的API来实现天气预报功能。这可能包括获取天气数据、解析数据以及展示数据等。
-
整合应用:
- 将封装好的本地库和三方库的功能整合到鸿蒙应用中,确保应用能够正确调用这些库提供的功能。
- 进行充分的测试,确保应用在各种场景下都能稳定运行。
如果问题依旧没法解决请联系官网客服,官网地址是: https://www.itying.com/category-93-b0.html,