HarmonyOS鸿蒙Next中flutter_bugly插件适配

HarmonyOS鸿蒙Next中flutter_bugly插件适配 【问题描述】:Flutter插件 flutter_bugly:Flutter 插件,适用于腾讯 Bugly、崩溃监控、崩溃分析、异常报告、应用更新、数据统计等。其他端适配正常, 鸿蒙端缺少适配

【问题现象】:Flutter插件 flutter_bugly:Flutter 插件,适用于腾讯 Bugly、崩溃监控、崩溃分析、异常报告、应用更新、数据统计等。其他端适配正常, 鸿蒙端缺少适配

cke_3480.png

【版本信息】:Flutter ohos分支

插件链接:flutter_bugly | Flutter package


更多关于HarmonyOS鸿蒙Next中flutter_bugly插件适配的实战教程也可以访问 https://www.itying.com/category-92-b0.html

4 回复

开发者您好,目前flutter_bugly已适配HarmonyOS,flutter_bugly是腾讯Bugly在Flutter生态的官方扩展插件,flutter_bugly依赖Bugly后台服务实现数据处理与分析,支持HarmonyOS运营统计、异常上报。

更多关于HarmonyOS鸿蒙Next中flutter_bugly插件适配的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


你需要为flutter_bugly Flutter 插件做鸿蒙(OpenHarmony/OHOS) 端的适配,让该插件在 Flutter OHOS 分支下能正常实现崩溃监控、异常报告、应用更新等核心功能,目前其他端适配完成仅鸿蒙端缺失支持。

核心适配思路

Flutter 插件的鸿蒙端适配遵循Flutter OHOS Channel 通信规范 + 鸿蒙原生代码实现 Bugly 核心能力的原则,核心分为 3 步:

  1. 改造插件的pubspec.yaml,声明鸿蒙端支持;
  2. 开发鸿蒙原生端(Java/ArkTS)代码,对接腾讯 Bugly 的鸿蒙原生 SDK,实现崩溃监控、异常上报等核心 API;
  3. 改造 Flutter Dart 层代码,增加鸿蒙端的平台判断和 Channel 通信逻辑。

前提准备

  1. 环境:Flutter OHOS 分支(已配置鸿蒙开发环境、DevEco Studio);
  2. 依赖:腾讯 Bugly鸿蒙原生 SDK(目前 Bugly 已提供鸿蒙端 SDK,支持崩溃监控、异常上报,应用更新需自行实现);
  3. 插件结构:确保flutter_bugly插件目录包含ohos/原生层目录(无则新建)。

第一步:改造插件配置文件(pubspec.yaml)

修改插件根目录的pubspec.yaml声明鸿蒙端支持,让 Flutter OHOS 分支能识别该插件的鸿蒙端实现,关键修改如下:

name: flutter_bugly
description: 腾讯Bugly Flutter插件,适配Android、iOS、HarmonyOS(OHOS),支持崩溃监控、异常上报、应用更新
version: 0.6.0+ohos1 # 版本号增加鸿蒙适配标识
homepage: https://github.com/crazecoder/flutter_bugly

flutter:
  plugin:
    platforms:
      android:
        package: com.crazecoder.flutterbugly
        pluginClass: FlutterBuglyPlugin
      ios:
        pluginClass: FlutterBuglyPlugin
      # 新增:鸿蒙端平台声明
      ohos:
        pluginClass: com.crazecoder.flutterbugly.FlutterBuglyPlugin
        fileName: FlutterBuglyPlugin.java # 原生代码入口文件

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0

flutter_lints:
  rules:
    - avoid_print

第二步:鸿蒙原生端(Java)适配开发

Flutter OHOS 分支目前对Java 原生层的支持更成熟,因此鸿蒙端原生代码选择Java开发,核心是实现 Channel 通信、集成 Bugly 鸿蒙 SDK、封装核心 API。

2.1 新建鸿蒙原生目录结构

在插件根目录新建如下目录(与 android/、ios / 同级),符合 Flutter OHOS 插件规范:

flutter_bugly/
├── ohos/
│   ├── src/
│   │   └── main/
│   │       ├── java/
│   │       │   └── com/
│   │       │       └── crazecoder/
│   │       │           └── flutterbugly/
│   │       │               └── FlutterBuglyPlugin.java # 核心原生类
│   │       └── resources/
│   └── build.gradle # 鸿蒙端构建配置
├── android/
├── ios/
├── lib/
└── pubspec.yaml

2.2 配置鸿蒙端 build.gradle

修改ohos/build.gradle,引入 Bugly 鸿蒙 SDK 和 Flutter OHOS 原生依赖:

plugins {
    id 'com.huawei.ohos.hap' version '3.0.0.0'
    id 'java'
}

// 引入Flutter OHOS原生SDK依赖
repositories {
    mavenCentral()
    // 腾讯Bugly鸿蒙SDK仓库
    maven { url 'https://developer.huawei.com/repo/' }
    maven { url 'https://dl.bintray.com/tencent-bugly/maven/' }
}

dependencies {
    // Flutter OHOS核心依赖
    implementation 'com.github.flutter-ohos:flutter:1.0.0'
    // 腾讯Bugly鸿蒙原生SDK(最新版本请参考官方)
    implementation 'com.tencent.bugly:crashreport-ohos:1.0.0'
    // 鸿蒙基础依赖
    implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
    implementation 'ohos:ohos-sdk:9'
}

ohos {
    compileSdkVersion 9
    defaultConfig {
        compatibleSdkVersion 9
        targetSdkVersion 9
    }
    buildTypes {
        release {
            minifyEnabled false
        }
    }
}

2.3 核心原生类实现(FlutterBuglyPlugin.java)

实现 Flutter 与鸿蒙的MethodChannel 通信,封装 Bugly 鸿蒙 SDK 的初始化、崩溃监控、手动异常上报、设备信息获取等核心功能(应用更新需自行扩展,Bugly 鸿蒙端暂未提供现成更新 SDK):

package com.crazecoder.flutterbugly;

import com.flutter.ohos.FlutterPlugin;
import com.flutter.ohos.MethodCall;
import com.flutter.ohos.MethodChannel;
import com.flutter.ohos.MethodChannel.MethodCallHandler;
import com.flutter.ohos.MethodChannel.Result;
import com.tencent.bugly.crashreport.CrashReport;
import ohos.aafwk.ability.AbilityPackage;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import java.util.Map;

/**
 * FlutterBugly鸿蒙端核心插件类
 */
public class FlutterBuglyPlugin implements FlutterPlugin, MethodCallHandler {
    // 日志标签
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00001, "FlutterBuglyOHOS");
    // Flutter与鸿蒙通信的Channel名称(需与Dart层一致)
    public static final String CHANNEL_NAME = "flutter_bugly";
    // 鸿蒙应用上下文
    private Context mContext;
    // MethodChannel实例
    private MethodChannel mChannel;

    @Override
    public void onAttachedToEngine(Context context, FlutterPlugin.Registrar registrar) {
        mContext = context;
        // 初始化MethodChannel
        mChannel = new MethodChannel(registrar.messenger(), CHANNEL_NAME);
        mChannel.setMethodCallHandler(this);
        HiLog.info(LABEL, "FlutterBugly鸿蒙端插件初始化成功");
    }

    @Override
    public void onMethodCall(MethodCall call, Result result) {
        // 根据Dart层调用的方法名,分发到对应实现
        switch (call.method) {
            case "initBugly":
                initBugly(call, result);
                break;
            case "postCatchedException":
                postCatchedException(call, result);
                break;
            case "getDeviceInfo":
                getDeviceInfo(result);
                break;
            case "checkUpgrade":
                // 应用更新:鸿蒙端暂自定义实现(示例返回暂不支持)
                result.success("{\"code\":-1,\"msg\":\"鸿蒙端应用更新暂未实现\"}");
                break;
            default:
                // 未实现的方法返回错误
                result.notImplemented();
                break;
        }
    }

    /**
     * 初始化Bugly鸿蒙SDK
     * Dart层传入参数:appId、debug模式、自定义参数等
     */
    private void initBugly(MethodCall call, Result result) {
        try {
            Map<String, Object> args = call.arguments();
            String appId = args.get("appId").toString();
            boolean debug = (boolean) args.get("debug");
            // Bugly鸿蒙SDK初始化(核心方法)
            CrashReport.initCrashReport(mContext, appId, debug);
            HiLog.info(LABEL, "Bugly鸿蒙SDK初始化成功,appId:%s,debug:%b", appId, debug);
            result.success(true);
        } catch (Exception e) {
            HiLog.error(LABEL, "Bugly初始化失败:%s", e.getMessage());
            result.error("INIT_FAILED", "Bugly鸿蒙SDK初始化失败:" + e.getMessage(), e);
        }
    }

    /**
     * 手动上报异常(对应Dart层的手动捕获异常上报)
     */
    private void postCatchedException(MethodCall call, Result result) {
        try {
            Map<String, Object> args = call.arguments();
            String message = args.get("message").toString();
            String stackTrace = args.get("stackTrace").toString();
            // 构造自定义异常并上报
            Exception exception = new Exception(message + "\n" + stackTrace);
            CrashReport.postException(exception);
            HiLog.info(LABEL, "手动异常上报成功:%s", message);
            result.success(true);
        } catch (Exception e) {
            HiLog.error(LABEL, "手动异常上报失败:%s", e.getMessage());
            result.error("REPORT_FAILED", "手动异常上报失败:" + e.getMessage(), e);
        }
    }

    /**
     * 获取设备信息(返回鸿蒙设备基础信息)
     */
    private void getDeviceInfo(Result result) {
        try {
            // 封装鸿蒙设备信息(可根据Bugly SDK扩展更多)
            String deviceInfo = "{\"os\":\"HarmonyOS\",\"osVersion\":\"" + ohos.system.version.SystemVersion.getSdkVersion() +
                    "\",\"model\":\"" + ohos.system.device.DeviceInfo.getDeviceModel() +
                    "\",\"manufacturer\":\"" + ohos.system.device.DeviceInfo.getManufacturer() + "\"}";
            result.success(deviceInfo);
        } catch (Exception e) {
            HiLog.error(LABEL, "获取设备信息失败:%s", e.getMessage());
            result.error("DEVICE_INFO_FAILED", "获取设备信息失败:" + e.getMessage(), e);
        }
    }

    @Override
    public void onDetachedFromEngine(FlutterPlugin.Registrar registrar) {
        // 插件销毁时释放资源
        mChannel.setMethodCallHandler(null);
        mContext = null;
        mChannel = null;
        HiLog.info(LABEL, "FlutterBugly鸿蒙端插件销毁");
    }
}

第三步:改造 Flutter Dart 层代码

修改插件lib/flutter_bugly.dart增加鸿蒙端的平台判断,并保证 Channel 通信方法与鸿蒙原生端一致,核心修改是补充TargetPlatform.ohos的判断,无需改动原有核心逻辑,关键代码如下:

import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

/// FlutterBugly核心类
class FlutterBugly {
  static const MethodChannel _channel = MethodChannel('flutter_bugly'); // 与鸿蒙原生端CHANNEL_NAME一致

  /// 初始化Bugly
  /// [appId] 各平台Bugly的AppId(鸿蒙端单独配置)
  /// [debug] 是否开启debug模式
  static Future<bool> initBugly({
    required String androidAppId,
    required String iosAppId,
    required String ohosAppId, // 新增:鸿蒙端AppId
    bool debug = false,
    Map<String, dynamic>? customParams,
  }) async {
    String appId;
    // 增加鸿蒙端平台判断(Flutter OHOS分支已支持TargetPlatform.ohos)
    if (defaultTargetPlatform == TargetPlatform.android) {
      appId = androidAppId;
    } else if (defaultTargetPlatform == TargetPlatform.iOS) {
      appId = iosAppId;
    } else if (defaultTargetPlatform == TargetPlatform.ohos) { // 鸿蒙端
      appId = ohosAppId;
    } else {
      throw UnsupportedError('当前平台不支持Bugly');
    }
    final Map<String, dynamic> args = {
      'appId': appId,
      'debug': debug,
      'customParams': customParams ?? {},
    };
    return await _channel.invokeMethod('initBugly', args) ?? false;
  }

  /// 手动上报异常(核心:Dart层未捕获异常/手动捕获异常上报)
  static Future<bool> postCatchedException({
    required String message,
    required String stackTrace,
  }) async {
    final Map<String, dynamic> args = {
      'message': message,
      'stackTrace': stackTrace,
    };
    return await _channel.invokeMethod('postCatchedException', args) ?? false;
  }

  /// 获取设备信息
  static Future<Map<String, dynamic>?> getDeviceInfo() async {
    final String result = await _channel.invokeMethod('getDeviceInfo') ?? '{}';
    return json.decode(result);
  }

  /// 检查更新(鸿蒙端暂未实现,返回自定义结果)
  static Future<Map<String, dynamic>?> checkUpgrade({
    bool isManual = false,
    bool isSilence = false,
  }) async {
    final Map<String, dynamic> args = {
      'isManual': isManual,
      'isSilence': isSilence,
    };
    final String result = await _channel.invokeMethod('checkUpgrade', args) ?? '{}';
    return json.decode(result);
  }

  /// 捕获Flutter全局未捕获异常(核心:Dart层崩溃监控)
  static void catchFlutterError({
    FlutterExceptionHandler? onError,
  }) {
    FlutterError.onError = (FlutterErrorDetails details) {
      // 先调用原有错误处理(如果有)
      if (onError != null) {
        onError(details);
      }
      // 上报到Bugly(鸿蒙端会通过原生层接收)
      postCatchedException(
        message: details.exception.toString(),
        stackTrace: details.stackTrace.toString(),
      );
    };
  }
}

第四步:鸿蒙端测试与集成

  1. 本地插件集成:在你的 Flutter OHOS 项目中,将改造后的flutter_bugly插件作为本地依赖引入(替代 pub 仓库依赖),修改项目pubspec.yaml

    dependencies:
      flutter:
        sdk: flutter
      flutter_bugly:
        path: ../flutter_bugly # 插件本地路径
    
  2. 配置鸿蒙端 Bugly AppId:在腾讯 Bugly 后台创建鸿蒙应用,获取专属 AppId(与 Android/iOS 分开);

  3. 项目初始化 Bugly:在 Flutter OHOS 项目的main.dart中初始化,示例如下:

    import 'package:flutter/material.dart';
    import 'package:flutter_bugly/flutter_bugly.dart';
    
    void main() {
      // 初始化Bugly(配置各平台AppId,重点传入ohosAppId)
      FlutterBugly.initBugly(
        androidAppId: "你的Android AppId",
        iosAppId: "你的iOS AppId",
        ohosAppId: "你的鸿蒙AppId", // 腾讯Bugly后台创建鸿蒙应用获取
        debug: true,
      );
      // 捕获Flutter全局未捕获异常
      FlutterBugly.catchFlutterError();
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: const Text('Bugly鸿蒙端测试')),
            body: Center(
              child: ElevatedButton(
                // 测试手动上报异常
                onPressed: () => FlutterBugly.postCatchedException(
                  message: "测试鸿蒙端手动异常",
                  stackTrace: "测试堆栈:main.dart:28",
                ),
                child: const Text('测试手动上报异常'),
              ),
            ),
          ),
        );
      }
    }
    
  4. 运行测试:使用 DevEco Studio 连接鸿蒙设备 / 模拟器,运行 Flutter OHOS 项目,点击按钮测试手动异常上报,崩溃后查看腾讯 Bugly 后台是否能接收到鸿蒙端的异常 / 崩溃数据。

第五步:扩展功能(可选)

目前上述适配实现了核心的崩溃监控、手动异常上报、设备信息获取,可根据需求扩展:

  1. 应用更新:Bugly 鸿蒙端暂未提供现成的更新 SDK,可基于鸿蒙原生的AbilityPackageNetwork实现版本检测、下载、安装逻辑,在FlutterBuglyPlugin.javacheckUpgrade方法中扩展;
  2. 自定义参数上报:在 Bugly 初始化时,通过CrashReport.setUserIdentifierCrashReport.putCustomKey添加用户信息、自定义参数(鸿蒙 SDK 支持);
  3. ANR 监控:Bugly 鸿蒙 SDK 已支持 ANR 监控,无需额外开发,初始化后自动开启;
  4. ArkTS 适配:如果需要基于 ArkTS 开发鸿蒙原生层,可将 Java 代码迁移为 ArkTS(Flutter OHOS 分支对 ArkTS 的支持正在完善,建议先使用 Java)。

适配注意事项

  1. Bugly SDK 版本:请关注腾讯 Bugly 官方文档,及时更新鸿蒙 SDK 的最新版本;
  2. Flutter OHOS 分支:确保使用最新的 Flutter OHOS 分支,避免 Channel 通信、原生依赖的兼容性问题;
  3. 鸿蒙 SDK 版本:上述代码基于鸿蒙 API 9开发,可根据需求适配 API 8/10;
  4. 权限配置:在鸿蒙应用的config.json中添加必要权限(网络、存储、设备信息):
    {
      "module": {
        "reqPermissions": [
          {
            "name": "ohos.permission.

鸿蒙Next中flutter_bugly插件适配

目前官方未提供原生支持。该插件依赖Android原生Bugly SDK,与鸿蒙Next的ArkTS/ArkUI框架不兼容。开发者需等待官方或社区发布适配版本,或自行基于鸿蒙崩溃服务(CrashService)开发替代插件。

在HarmonyOS Next上,flutter_bugly 插件目前无法直接使用,因为它尚未提供对鸿蒙平台的官方适配支持。

该插件主要依赖于原生的Android/iOS SDK实现其功能。在鸿蒙(Ohos)Flutter分支中,由于缺乏对应的鸿蒙原生(ArkTS)实现层,插件无法被正确注册和调用,因此会报出“缺少适配”的错误。

当前可行的解决方案:

  1. 联系插件维护者:在插件的GitHub仓库提交Issue,请求增加对HarmonyOS(Ohos)平台的支持。这是最根本的解决途径。
  2. 自行开发鸿蒙适配层:如果你有较强的原生开发能力,可以尝试为flutter_bugly插件开发一个鸿蒙端的实现。这需要:
    • 在插件的flutter_bugly包中创建ohos目录。
    • 使用ArkTS语言,参照其Android/iOS端的原生代码逻辑,实现鸿蒙端的通道(MethodChannel)处理。
    • 集成腾讯Bugly的鸿蒙原生SDK(如果腾讯已提供)或寻找功能等效的鸿蒙崩溃收集、更新检测库。
  3. 寻找或开发替代插件:寻找其他已支持HarmonyOS的Flutter崩溃收集、应用更新插件,或者基于鸿蒙原生能力自行封装一个新的Flutter插件。
  4. 暂时移除或条件编译:在鸿蒙构建版本中,通过条件编译或其他方式排除此插件的使用,并采用其他方式(如鸿蒙原生错误管理)处理崩溃和更新需求。

总结:核心问题是第三方Flutter插件的生态适配滞后于HarmonyOS Next的发展。目前需要等待插件作者更新或自行进行原生端的适配开发。在官方适配完成前,该插件在鸿蒙项目中将无法正常工作。

回到顶部