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

Flutter三方库鸿蒙实战:基于http和json_annotation的天气查询App(支持HarmonyOS 6.0+ API 20+)
本文通过一个完整的天气查询项目,演示如何使用Flutter在鸿蒙(HarmonyOS 6.0以上,API Level 20+)平台上进行跨端开发,重点讲解三方库(http网络库、json_serializable序列化库)的集成与使用方法,最终将应用运行在鸿蒙设备上。

目录
环境搭建

创建Flutter鸿蒙项目

配置依赖与三方库

实现网络请求与数据解析

构建用户界面

集成与运行

总结与扩展

  1. 环境搭建
    在开始之前,请确保你已经准备好以下环境(满足鸿蒙6.0+、API 20+的要求):

DevEco Studio(≥5.0.0,支持HarmonyOS 6.0)

Flutter SDK(≥3.22,使用支持OpenHarmony/HarmonyOS的flutter-ohos分支)

HarmonyOS SDK(API Level 20 或更高,对应HarmonyOS 6.0及以上)

Node.js(≥18.0)

1.1 安装Flutter for HarmonyOS
由于官方Flutter尚未直接支持鸿蒙,我们需要使用社区维护的flutter-ohos版本。执行以下命令:

bash
git clone https://gitee.com/openharmony-sig/flutter_flutter.git -b stable flutter-ohos
export PATH=“$PATH:pwd/flutter-ohos/bin”
然后运行flutter doctor,确保OHOS一栏显示“工具链可用”,并且检查到鸿蒙SDK路径。

1.2 配置鸿蒙设备(API 20+)
使用DevEco Studio创建一个模拟器,选择Phone类型,系统镜像要求HarmonyOS 6.0 (API 20+)。

或连接真机(系统版本≥HarmonyOS 6.0),开启USB调试。

  1. 创建Flutter鸿蒙项目
    创建一个新项目,项目类型选择“鸿蒙应用”:

bash
flutter create --platforms ohos weather_app
cd weather_app
此时项目目录下会生成ohos文件夹,这是鸿蒙原生工程入口。

打开ohos/entry/src/main/ets/entryability/EntryAbility.ets,确保它能正确加载Flutter入口(默认已配置)。

注意:由于我们使用API 20+,请检查ohos/build-profile.json5中的compileSdkVersion和compatibleSdkVersion是否≥20。若不满足,手动修改为20或更高。

示例配置(ohos/build-profile.json5):

json
{
“app”: {
“products”: [{
“compileSdkVersion”: 20,
“compatibleSdkVersion”: 20,

}]
}
}
3. 配置依赖与三方库
我们将使用以下三方库:

http: 发起网络请求获取天气数据

json_annotation + json_serializable: 自动解析JSON

打开pubspec.yaml,添加:

yaml
dependencies:
flutter:
sdk: flutter
http: ^1.2.0
json_annotation: ^4.9.0

dev_dependencies:
build_runner: ^2.4.9
json_serializable: ^6.8.0
运行flutter pub get安装依赖。

  1. 实现网络请求与数据解析
    4.1 设计数据模型
    我们以和风天气的公开API为例(需申请免费API Key)。新建lib/models/weather.dart:

dart
// 引入json注解库
import ‘package:json_annotation/json_annotation.dart’;

// 这一行是自动生成代码的关联指令,必须写
part ‘weather.g.dart’;

// 天气主模型
@JsonSerializable()
class Weather {
final String city; // 城市名
final String temperature; // 温度(摄氏度)
final String condition; // 天气状况描述

Weather({
required this.city,
required this.temperature,
required this.condition,
});

// 从JSON生成对象
factory Weather.fromJson(Map<String, dynamic> json) => _$WeatherFromJson(json);

// 对象转JSON(可选)
Map<String, dynamic> toJson() => _$WeatherToJson(this);
}
然后运行命令生成解析代码:

bash
flutter pub run build_runner build
执行后会生成weather.g.dart,其中包含了_KaTeX parse error: Expected group after '_' at position 17: …eatherFromJson和_̲WeatherToJson的具体实现。

4.2 编写网络请求服务
创建lib/services/weather_service.dart:

dart
import ‘package:http/http.dart’ as http;
import ‘dart:convert’;
import ‘…/models/weather.dart’;

class WeatherService {
// 请替换成你的和风天气API Key
static const String apiKey = “YOUR_API_KEY”;
static const String baseUrl = “https://devapi.qweather.com/v7/weather/now”;

// 根据城市名获取实时天气
Future fetchWeather(String city) async {
// 实际和风天气需要先获取LocationID,为简化,此处使用mock或直接请求demo接口
// 注意:以下URL仅为示例,实际需要注册获取key并替换为真实接口
final url = Uri.parse(“baseUrl?location=baseUrl?location=baseUrl?location=city&key=$apiKey”);

try {
  final response = await http.get(url);
  if (response.statusCode == 200) {
    final Map<String, dynamic> data = json.decode(response.body);
    // 根据实际返回结构解析(这里简化处理)
    final now = data['now'];
    return Weather(
      city: city,
      temperature: now['temp'].toString(),
      condition: now['text'],
    );
  } else {
    throw Exception("请求失败:${response.statusCode}");
  }
} catch (e) {
  // 为演示效果,返回模拟数据(避免因网络或key问题阻塞流程)
  return Weather(
    city: city,
    temperature: "22",
    condition: "晴",
  );
}

}
}
说明:真实开发时请替换API Key并正确解析。上述代码含异常回退模拟数据,方便新手快速体验。

  1. 构建用户界面
    创建lib/main.dart,完成完整的UI交互:

dart
import ‘package:flutter/material.dart’;
import ‘services/weather_service.dart’;
import ‘models/weather.dart’;

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘鸿蒙天气’,
theme: ThemeData(primarySwatch: Colors.blue),
home: const WeatherPage(),
);
}
}

class WeatherPage extends StatefulWidget {
const WeatherPage({super.key});

@override
State createState() => _WeatherPageState();
}

class _WeatherPageState extends State {
final TextEditingController _cityController = TextEditingController();
Weather? _weather;
bool _loading = false;
String _error = ‘’;

final WeatherService _weatherService = WeatherService();

// 查询天气方法
Future _queryWeather() async {
final city = _cityController.text.trim();
if (city.isEmpty) {
setState(() {
_error = ‘请输入城市名’;
});
return;
}

setState(() {
  _loading = true;
  _error = '';
  _weather = null;
});

try {
  final weather = await _weatherService.fetchWeather(city);
  setState(() {
    _weather = weather;
    _loading = false;
  });
} catch (e) {
  setState(() {
    _error = e.toString();
    _loading = false;
  });
}

}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(‘Flutter三方库鸿蒙天气查询’),
backgroundColor: Colors.blueAccent,
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
// 输入框和按钮
Row(
children: [
Expanded(
child: TextField(
controller: _cityController,
decoration: const InputDecoration(
hintText: ‘请输入城市名,例如:Beijing’,
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 10),
ElevatedButton(
onPressed: _queryWeather,
child: const Text(‘查询’),
),
],
),
const SizedBox(height: 20),
// 加载指示器
if (_loading) const CircularProgressIndicator(),
// 错误信息
if (_error.isNotEmpty)
Text(_error, style: const TextStyle(color: Colors.red)),
// 天气数据显示
if (_weather != null) …[
const SizedBox(height: 20),
Card(
elevation: 4,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
_weather!.city,
style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text(
‘${_weather!.temperature}°C’,
style: const TextStyle(fontSize: 48),
),
const SizedBox(height: 10),
Text(
_weather!.condition,
style: const TextStyle(fontSize: 20),
),
],
),
),
),
],
],
),
),
);
}
}
代码说明
WeatherService封装了网络请求逻辑,使用http库发起GET请求。

json_annotation自动生成解析代码,使模型层简洁。

UI使用StatefulWidget管理加载状态和数据显示,提供良好的用户体验。

  1. 集成与运行
    6.1 配置鸿蒙应用权限
    由于需要访问网络,必须在鸿蒙工程中申请权限。打开ohos/entry/src/main/module.json5,在requestPermissions中添加:

json
{
“name”: “ohos.permission.INTERNET”
}
6.2 确保API版本符合要求
检查ohos/entry/build-profile.json5中的compileSdkVersion和compatibleSdkVersion均设置为20或更高。例如:

json
{
“apiType”: “stageMode”,
“buildOption”: {},
“targets”: [
{
“name”: “default”,
“runtimeOS”: “HarmonyOS”,
“config”: {
“compileSdkVersion”: 20,
“compatibleSdkVersion”: 20
}
}
]
}
6.3 运行应用
确保鸿蒙设备或模拟器(系统≥HarmonyOS 6.0)已启动,执行:

bash
flutter run -d ohos
第一次运行时会编译鸿蒙原生部分,稍等片刻。成功后,你将看到如下界面:

输入城市名(如“Shanghai”)

点击“查询”,显示天气数据(模拟或真实数据)

6.4 真机调试提示
如果使用真机,请确保鸿蒙系统版本≥HarmonyOS 6.0。

若遇到签名问题,在DevEco Studio中完成自动签名(File → Project Structure → Signing)。

  1. 总结与扩展
    通过本文的实践,你完成了以下内容:

环境搭建:配置支持HarmonyOS 6.0+ API 20+的Flutter开发环境。

三方库使用:集成了http和json_annotation库,实现了网络请求和数据自动解析。

完整项目:构建了一个具备输入查询、网络请求、结果显示的天气应用,并成功运行在鸿蒙设备上。

扩展建议
将API替换为真实服务(和风天气、心知天气等),注意处理异步错误和加载状态。

增加本地存储(使用shared_preferences库缓存最近查询的城市)。

使用provider或riverpod进行状态管理,优化代码结构。

适配鸿蒙的分布式能力,例如跨设备流转天气信息。

Flutter跨端开发在鸿蒙平台上的潜力巨大,社区的三方库生态正逐步完善。希望本文能帮助你快速上手鸿蒙跨端开发,享受一次编写、多端运行的乐趣。

附录:常见问题

Q: 运行flutter run -d ohos报错“No connected devices”?
A: 检查DevEco Studio是否启动了模拟器(API 20+),或执行flutter devices查看设备列表。

Q: 鸿蒙编译失败,提示“ohpm”找不到?
A: 需要安装ohpm,并在DevEco Studio中设置OHPM路径(通常随IDE自带,检查环境变量)。

Q: 网络请求失败?
A: 确认鸿蒙设备已联网,且module.json5中已添加INTERNET权限,同时检查API版本是否满足20+。

Q: json_serializable生成代码时报错?
A: 确保part ‘weather.g.dart’;和注解正确,运行flutter clean后重新生成。

完整示例源码可参考:https://gitee.com/example/weather_ohos_demo(示例链接)

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐