flutter 鸿蒙化插件开发横空出世

前言导读

最近呢有同学让我更新flutter 鸿蒙化插件的开发,趁着有时间我就分享一下。内容包括插件工程的创建还有如何开发等等,那么废话不多说我们正式开始。

效果图

具体实现

创建插件工程
dart 复制代码
flutter create -t plugin --platforms ohos,android,ios <plugin_name>

导入我们的插件工程

  • 1 我们的lib目录下面编写我们的插件和原生交互的dart代码

  • 2 example 下面是我们调试插件的代码

  • 3 ohos 是我们的插件原生部分代码

我们选直接运行下我们的项目 让devceo studio 拉一下我们的gradle

我们打开example 项目下面的ohos工程 (谨记不是根目录下面的ohos工程)

然后让devceo studio 构建

DemopluginPlugin就是我们插件原生代码 在这里编写和我们的flutter交互的代码

这个demo我们一共编写了 获取鸿蒙系统版本号和toast的案例

获取鸿蒙系统版本号

arkts 复制代码
if (call.method == "getPlatformVersion") {
  result.success("OpenHarmony "+deviceInfo.distributionOSVersion)
}

toast

arkts 复制代码
 if(call.method=='toast') {
  let str:string=call.argument('param') as string;
  console.log("str-- > "+str);

  prompt.showToast({
    message:str
  })

}

这里需要注意我们flutter 端 是通过map传递参数给我们鸿蒙next端的

dart 复制代码
@override
 toast(String str) async {
  Map<String,dynamic>user={
    'param':str
  };
   await methodChannel.invokeMethod<String>('toast',user);
}

完整插件原始鸿蒙next代码

arkts 复制代码
import {
  FlutterPlugin,
  FlutterPluginBinding,
  MethodCall,
  MethodCallHandler,
  MethodChannel,
  MethodResult,
} from '@ohos/flutter_ohos';
import deviceInfo from '@ohos.deviceInfo';
import { prompt } from '@kit.ArkUI';


/** DemopluginPlugin **/
export default class DemopluginPlugin implements FlutterPlugin, MethodCallHandler {
  private channel: MethodChannel | null = null;

  constructor() {
  }

  getUniqueClassName(): string {
    return "DemopluginPlugin"
  }

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "demoplugin");
    this.channel.setMethodCallHandler(this)
  }

  onDetachedFromEngine(binding: FlutterPluginBinding): void {
    if (this.channel != null) {
      this.channel.setMethodCallHandler(null)
    }
  }

  onMethodCall(call: MethodCall, result: MethodResult): void {
    if (call.method == "getPlatformVersion") {
      result.success("OpenHarmony "+deviceInfo.distributionOSVersion)
    } else  if(call.method=='toast') {
      let str:string=call.argument('param') as string;
      console.log("str-- > "+str);

      prompt.showToast({
        message:str
      })

    }else {
      result.notImplemented()
    }
  }
}

flutter端插件代码实现

我们先再插件父类抽象类里面 定义我们跟原生端交互的方法

dart 复制代码
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

import 'demoplugin_method_channel.dart';

abstract class DemopluginPlatform extends PlatformInterface {
  /// Constructs a DemopluginPlatform.
  DemopluginPlatform() : super(token: _token);

  static final Object _token = Object();

  static DemopluginPlatform _instance = MethodChannelDemoplugin();

  /// The default instance of [DemopluginPlatform] to use.
  ///
  /// Defaults to [MethodChannelDemoplugin].
  static DemopluginPlatform get instance => _instance;

  /// Platform-specific implementations should set this with their own
  /// platform-specific class that extends [DemopluginPlatform] when
  /// they register themselves.
  static set instance(DemopluginPlatform instance) {
    PlatformInterface.verifyToken(instance, _token);
    _instance = instance;
  }

  Future<String?> getPlatformVersion() {
    throw UnimplementedError('platformVersion() has not been implemented.');
  }

  @override
  toast(String str) async {
    throw UnimplementedError('platformVersion() has not been implemented.');
  }
}

然后再我们的 MethodChannelComeplugin 类里面实现这些方法

dart 复制代码
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import 'demoplugin_platform_interface.dart';

/// An implementation of [DemopluginPlatform] that uses method channels.
class MethodChannelDemoplugin extends DemopluginPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('demoplugin');

  @override
  Future<String?> getPlatformVersion() async {
    final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
    return version;
  }



  @override
   toast(String str) async {
    Map<String,dynamic>user={
      'param':str
    };
     await methodChannel.invokeMethod<String>('toast',user);
  }
}

我们通过 MethodChannel 来注册我们的交互的通信的协议demoplugin 这个要跟我的原生端保持一致

flutter 端

dart 复制代码
@visibleForTesting
final methodChannel = const MethodChannel('demoplugin');

鸿蒙原生端

arkts 复制代码
onAttachedToEngine(binding: FlutterPluginBinding): void {
  this.channel = new MethodChannel(binding.getBinaryMessenger(), "demoplugin");
  this.channel.setMethodCallHandler(this)
}

然后我们定义 Demoplugin 定义对应的对外方法 给我们的 example 调试工程调用

dart 复制代码
import 'demoplugin_platform_interface.dart';

class Demoplugin {
  Future<String?> getPlatformVersion() {
    return DemopluginPlatform.instance.getPlatformVersion();
  }


  @override
  toast(String str) async {
    return DemopluginPlatform.instance.toast(str);
  }

}

我们在Demoplugin 里面里面返回我们的 DemopluginPlatform 里面的结果

然后我们在 example里面去调用

获取鸿蒙next系统版本号调用
dart 复制代码
Future<void> initPlatformState() async {
  String platformVersion;
  // Platform messages may fail, so we use a try/catch PlatformException.
  // We also handle the message potentially returning null.
  try {
    platformVersion =
        await _demopluginPlugin.getPlatformVersion() ?? 'Unknown platform version';
  } on PlatformException {
    platformVersion = 'Failed to get platform version.';
  }

  // If the widget was removed from the tree while the asynchronous platform
  // message was in flight, we want to discard the reply rather than calling
  // setState to update our non-existent appearance.
  if (!mounted) return;

  setState(() {
    _platformVersion = platformVersion;
  });
}
toast调用
dart 复制代码
@override
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
      ),
      body: Center(
        child: Column(
          children: [
            Text('Running on: $_platformVersion\n'),
            ElevatedButton(onPressed: ()=>{
              _demopluginPlugin.toast("测试数据")

            }, child: Text("点击toast"))
          ],
        )
      ),
    ),
  );
}

最后总结

到此我们的flutter鸿蒙化 插件开发我们就讲完了,那么如何打包插件发布还有和其他端交互例如 ios还有鸿蒙,我们在后面我们补上去,因为篇幅有限我这边就不展开讲,原理都差不多 也是使用Methodchannel 交互的,如果同学有兴趣可以自己研究 也可以继续等待老师后续的更新,今天的文章就讲到这里,, 今天的文章就讲到这里有兴趣的 关注我B站教程 了解更多鸿蒙开发的知识 可以关注坚果派公众号 。 谢谢

如果想看Flutter插件开发化android交互在这里

flutter 插件开发化android 交互

课程地址

flutter开发鸿蒙next零基础到精通教程

项目内容:

1 Flutter 鸿蒙化开发环境搭建和项目运行介绍和实战使用
2 Flutter 鸿蒙化flutter页面添加到现有的鸿蒙项目中
3 Flutter鸿蒙化之flutter代码和鸿蒙next原生代码通信 MethodChannel 方式通信
4 Flutter鸿蒙化之flutter代码和鸿蒙next原生代码通信 EventChannel 方式通信
5 Flutter鸿蒙化之flutter代码和鸿蒙next原生代码通信 BasicMessageChannel 方式通信 实现透传
6 Flutter 鸿蒙化PlatformView实现混合渲染
7 Flutter 鸿蒙化插件开发
相关推荐
coder_pig7 小时前
跟🤡杰哥一起学Flutter (三十四、玩转Flutter手势✋)
前端·flutter·harmonyos
simple丶8 小时前
【HarmonyOS】鸿蒙蓝牙连接与通信技术
harmonyos·arkts·arkui
前端世界9 小时前
HarmonyOS开发实战:鸿蒙分布式生态构建与多设备协同发布全流程详解
分布式·华为·harmonyos
Jalor10 小时前
Flutter + 鸿蒙 | Flutter 跳转鸿蒙原生界面
flutter·harmonyos
zhanshuo11 小时前
开发者必看!如何在HarmonyOS中快速调用摄像头功能
harmonyos
HMSCore11 小时前
借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”
harmonyos
zhanshuo11 小时前
鸿蒙UI开发全解:JS与Java双引擎实战指南
前端·javascript·harmonyos
HarmonyOS小助手12 小时前
闯入鸿蒙:浪漫、理想与「草台班子」
harmonyos·鸿蒙·harmonyos next·鸿蒙生态
HarmonyOS_SDK12 小时前
借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”
harmonyos