Skip to content

插件开发与鸿蒙适配

当 Flutter 提供的 API 无法满足需求时,你需要通过平台通道(Platform Channel)调用原生代码,或开发自定义插件。

平台通道(Platform Channel)

Flutter 与原生平台之间通过 Platform Channel 通信:

通道类型通信模式适用场景
MethodChannel一次性调用,有返回值调用原生方法
EventChannel持续数据流监听原生事件
BasicMessageChannel双向消息传递自定义通信协议

MethodChannel — 方法通道

Flutter 端调用原生方法:

dart
// Flutter 端
import 'package:flutter/services.dart';

class BatteryService {
  static const _channel = MethodChannel('com.example/battery');

  static Future<int> getBatteryLevel() async {
    try {
      final level = await _channel.invokeMethod<int>('getBatteryLevel');
      return level!;
    } on PlatformException catch (e) {
      print('获取电池电量失败: ${e.message}');
      return -1;
    }
  }
}

Android 端实现(Kotlin):

文件位置:android/app/src/main/kotlin/.../MainActivity.kt

kotlin
class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/battery")
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "getBatteryLevel" -> {
                        val level = getBatteryLevel()
                        if (level != -1) {
                            result.success(level)
                        } else {
                            result.error("UNAVAILABLE", "Battery level not available", null)
                        }
                    }
                    else -> result.notImplemented()
                }
            }
    }

    private fun getBatteryLevel(): Int {
        val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
        return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
    }
}

iOS 端实现(Swift):

文件位置:ios/Runner/AppDelegate.swift

swift
@main
@objc class AppDelegate: FlutterAppDelegate {
    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        let controller = window?.rootViewController as? FlutterViewController
        let batteryChannel = FlutterMethodChannel(name: "com.example/battery",
                                                   binaryMessenger: controller!.binaryMessenger)

        batteryChannel.setMethodCallHandler { (call, result) in
            switch call.method {
            case "getBatteryLevel":
                let device = UIDevice.current
                device.isBatteryMonitoringEnabled = true
                let level = Int(device.batteryLevel * 100)
                result(level)
            default:
                result(FlutterMethodNotImplemented)
            }
        }

        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

插件项目结构

创建插件项目

bash
# 官方版(不支持 ohos)
flutter create --template=plugin --platforms=android,ios my_plugin

# flutter-ohos 定制版(支持 ohos)
flutter create --template=plugin --platforms=android,ios,ohos my_plugin

插件目录结构

my_plugin/
├── lib/                     # Dart 代码
│   └── my_plugin.dart       # 插件 API
├── android/                 # Android 原生实现
│   └── src/main/kotlin/
├── ios/                     # iOS 原生实现
│   └── Classes/
├── ohos/                    # 鸿蒙原生实现
│   └── entry/src/main/
├── example/                 # 示例 App
│   └── lib/
├── pubspec.yaml             # 插件配置
└── README.md

pubspec.yaml 配置

yaml
name: my_plugin
description: 自定义插件
version: 0.1.0

dependencies:
  flutter:
    sdk: flutter

flutter:
  plugin:
    platforms:
      android:
        package: com.example.my_plugin
        pluginClass: MyPlugin
      ios:
        pluginClass: MyPlugin
      ohos:
        pluginClass: MyPlugin

鸿蒙适配要点

鸿蒙插件结构

鸿蒙插件的实现放在 ohos/ 目录下,使用 ArkTS 语言:

ohos/
└── entry/
    └── src/main/
        ├── ets/
        │   └── plugin/MyPlugin.ts
        └── module.json5

鸿蒙端 MethodChannel 实现

typescript
import { FlutterPlugin, MethodCall, MethodResult } from '@ohos/flutter_ohos';

export class MyPlugin implements FlutterPlugin {
  getUniqueClassName(): string {
    return 'MyPlugin';
  }

  onMethodCall(call: MethodCall, result: MethodResult): void {
    switch (call.method) {
      case 'getBatteryLevel':
        // 鸿蒙获取电池电量
        result.success(85);
        break;
      default:
        result.notImplemented();
    }
  }
}

鸿蒙适配注意事项

  1. 权限:鸿蒙的权限声明在 module.json5 中,与 Android 的 AndroidManifest.xml 不同
  2. API 差异:部分 Android API 在鸿蒙上有不同的对应 API
  3. 线程模型:鸿蒙的任务模型与 Android 不同,需注意异步处理
  4. UI 组件:鸿蒙使用 ArkUI,Flutter 通过自绘引擎渲染,一般不受影响
  5. 生态:鸿蒙的第三方库生态仍在发展中,某些 Android 库可能没有鸿蒙替代品

插件开发速查

需求方案
调用原生方法MethodChannel
监听原生事件EventChannel
跨平台插件分别实现 Android/iOS/鸿蒙
分享平台代码在 Dart 层封装通用逻辑

下一步

基于 Flutter 官方文档整理