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

Flutter 三方库 dio 的 OpenHarmony 鸿蒙化适配实践

引言

随着 OpenHarmony 生态的不断发展,越来越多的开发者开始探索如何将成熟的 Flutter 生态迁移到鸿蒙平台。作为 Flutter 生态中最流行的网络请求库,dio 的鸿蒙化适配成为许多开发者关注的焦点。本文将详细介绍如何在 Flutter-OH 项目中集成和适配 dio 库,解决实际开发中遇到的问题,并提供完整的实践案例。

一、环境准备与项目初始化

1.1 开发环境配置

在开始之前,确保您的开发环境满足以下要求:

  • DevEco Studio 版本:4.1 及以上
  • Flutter SDK 版本:3.16.0 及以上
  • OpenHarmony SDK 版本:4.1.0.400 及以上

1.2 创建 Flutter-OH 项目

使用 DevEco Studio 创建新的 Flutter-OH 项目:

flutter create --platforms=ohos my_cross_platform_app
cd my_cross_platform_app

二、集成 dio 依赖

2.1 添加依赖到 pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.0
  cupertino_icons: ^1.0.8

2.2 获取依赖

flutter pub get

三、dio 在 OpenHarmony 上的适配实践

3.1 基础配置封装

创建 lib/utils/http_manager.dart 文件:

import 'package:dio/dio.dart';

class HttpManager {
  static final HttpManager _instance = HttpManager._internal();
  late Dio _dio;

  factory HttpManager() => _instance;

  HttpManager._internal() {
    BaseOptions options = BaseOptions(
      baseUrl: 'https://api.example.com',
      connectTimeout: const Duration(seconds: 10),
      receiveTimeout: const Duration(seconds: 10),
      sendTimeout: const Duration(seconds: 10),
    );

    _dio = Dio(options);
    _setupInterceptors();
  }

  void _setupInterceptors() {
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        options.headers['Content-Type'] = 'application/json';
        return handler.next(options);
      },
      onResponse: (response, handler) {
        return handler.next(response);
      },
      onError: (DioException e, handler) {
        return handler.next(e);
      },
    ));
  }

  Future<Response> get(String path, {Map<String, dynamic>? queryParameters}) {
    return _dio.get(path, queryParameters: queryParameters);
  }

  Future<Response> post(String path, {dynamic data}) {
    return _dio.post(path, data: data);
  }

  Future<Response> put(String path, {dynamic data}) {
    return _dio.put(path, data: data);
  }

  Future<Response> delete(String path) {
    return _dio.delete(path);
  }
}

3.2 实际业务场景封装

创建 lib/services/api_service.dart 文件:

import 'package:dio/dio.dart';
import '../utils/http_manager.dart';

class ApiService {
  final HttpManager _httpManager = HttpManager();

  Future<Response> fetchUserInfo(String userId) async {
    try {
      Response response = await _httpManager.get(
        '/users/$userId',
        queryParameters: {'include': 'profile'},
      );
      return response;
    } catch (e) {
      rethrow;
    }
  }

  Future<Response> createUser(Map<String, dynamic> userData) async {
    try {
      Response response = await _httpManager.post('/users', data: userData);
      return response;
    } catch (e) {
      rethrow;
    }
  }

  Future<Response> updateUser(String userId, Map<String, dynamic> userData) async {
    try {
      Response response = await _httpManager.put('/users/$userId', data: userData);
      return response;
    } catch (e) {
      rethrow;
    }
  }

  Future<Response> deleteUser(String userId) async {
    try {
      Response response = await _httpManager.delete('/users/$userId');
      return response;
    } catch (e) {
      rethrow;
    }
  }
}

3.3 UI 层集成示例

lib/main.dart 中集成网络请求:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'services/api_service.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Dio OH Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

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

  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final ApiService _apiService = ApiService();
  String _responseText = '';
  bool _isLoading = false;

  Future<void> _fetchData() async {
    setState(() {
      _isLoading = true;
      _responseText = '';
    });

    try {
      Response response = await _apiService.fetchUserInfo('123');
      setState(() {
        _responseText = '请求成功!\nStatus: ${response.statusCode}\nData: ${response.data}';
      });
    } catch (e) {
      setState(() {
        _responseText = '请求失败: $e';
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Dio OH 适配示例'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: _isLoading ? null : _fetchData,
                child: _isLoading
                    ? const CircularProgressIndicator()
                    : const Text('发起网络请求'),
              ),
              const SizedBox(height: 20),
              Expanded(
                child: SingleChildScrollView(
                  child: Text(_responseText),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

四、OpenHarmony 平台特殊适配处理

4.1 网络权限配置

ohos/entry/src/main/module.json5 中添加网络权限:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": ["phone", "tablet"],
    "permissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ],
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntrance": "./ets/entryability/EntryAbility.ets",
        "description": "$string:entry_ability_desc",
        "icon": "$media:app_icon",
        "label": "$string:entry_ability_label",
        "type": "page",
        "launchType": "standard"
      }
    ]
  }
}

4.2 TLS 证书配置(HTTPS 访问)

对于需要 HTTPS 访问的场景,需要在 OpenHarmony 侧配置证书:

void _setupSSLCertificate(Dio dio) {
  dio.httpClientAdapter = HttpAdapter(
    onHttpClientCreate: (client) {
      client.badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
      return client;
    },
  );
}

五、常见问题与解决方案

5.1 问题:网络请求超时

原因:OpenHarmony 平台对网络请求有更严格的超时限制。

解决方案

BaseOptions options = BaseOptions(
  connectTimeout: const Duration(seconds: 30),
  receiveTimeout: const Duration(seconds: 30),
);

5.2 问题:HTTPS 证书验证失败

原因:OpenHarmony 默认会严格验证 SSL 证书。

解决方案:在开发环境可以暂时忽略证书验证,生产环境建议配置正确的证书。

5.3 问题:中文乱码

原因:响应数据编码问题。

解决方案

response.headers.contentType = ContentType.parse('application/json; charset=utf-8');

六、性能优化建议

6.1 请求缓存策略

dio.interceptors.add(CacheInterceptor(
  options: CacheOptions(
    store: MemCacheStore(),
    policy: CachePolicy.request,
    hitCacheOnErrorExcept: [],
    maxStale: const Duration(days: 7),
  ),
));

6.2 请求重试机制

dio.interceptors.add(RetryInterceptor(
  dio: dio,
  options: const RetryOptions(
    retries: 3,
    retryInterval: const Duration(seconds: 1),
    retryEvaluator: (error) => error.type == DioExceptionType.connectionTimeout,
  ),
));

七、运行验证

7.1 构建命令

flutter build ohos

7.2 设备运行

确保设备已连接并授权,运行以下命令:

flutter run -d <device_id>

八、总结

通过本文的实践,我们成功完成了 dio 库在 Flutter-OH 项目中的集成与适配。关键步骤包括:

  1. 正确配置开发环境和项目依赖
  2. 创建统一的网络请求管理类
  3. 添加必要的权限配置
  4. 处理平台特定的兼容性问题
  5. 实施性能优化策略

dio 作为 Flutter 生态中最优秀的网络库之一,其在 OpenHarmony 平台上的适配相对顺畅。开发者只需关注平台特定的权限配置和网络特性,即可实现高效稳定的网络请求功能。

本文仓库地址:https://atomgit.com/your_username/flutter-dio-oh-adaptation


参考文献

  • OpenHarmony 官方文档:https://gitee.com/openharmony/docs
  • dio 官方文档:https://pub.dev/packages/dio
  • Flutter for OpenHarmony 文档:https://gitee.com/openharmony-sig/flutter
Logo

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

更多推荐