#星光不负 码向未来# 2025我的鸿蒙布道之旅记录 精华
前言导读
这一次1024程序员节 受邀去深圳专场做技术分享,也是非常荣幸得到官方和51cto的肯定和支持。之前都是线上讲课, 线下和各位开发者面对面交流确实比较少,内心非常的激动,收获也非常多。
自我介绍
大家好我是徐庆 ,这里是我的自我介绍
徐庆HDE 曾经任职9377游戏公司担任高级安卓工程师。拥有十年移动端开发经验,多次参加CSDN 等平台举办的线下课程,2024年第31期掘金移动端优质作者榜排名第一,深圳鸿蒙数字技能人才培养课程优质讲师。
我是一名安卓开发者同时也是一名鸿蒙开发者,负责公司鸿蒙项目的开发和上架 此外了在自己的休息时间也在
B站录制了很多关于鸿蒙开发的一系列的教程
鸿蒙布道之旅
跨平台适配的痛点和难点
鸿蒙next 也发布了快2年了,虽然主流的应用基本适配了,但是那些中小型公司,因为使用跨平台的技术去开发安卓和ios 所以呢 想让他们重头开始使用arkts 重写一遍鸿蒙应用 几乎是不可能的,所以这一次1024的活动受邀 就来分享flutter框架助力鸿蒙next开发和适配
Flutter和HarmonyOS结合的价值与趋势
-
降低开发成本
-
加快迭代和更新
-
广泛的设备覆盖,扩大潜在用户群
-
跨平台开发成为软件行业的主流趋势
整个活动介绍

活动主要有深圳市企业联合会副秘书长 李昭双 致辞 还有三位老师进行技术分享
分享技术分别有
-
Flutter框架助力鸿蒙原生应用开发 徐庆老师
-
产教融合共育鸿蒙生态 刘洋老师
-
鸿蒙生态下的短距通信技术全景与应用实战 陈坤老师
我负责演讲的主题是 Flutter框架助力鸿蒙原生应用开发

主要分享以下几个点

案例分享
效果图


具体实现
-
创建插件工程
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的案例
-
获取鸿蒙系统版本号
if (call.method == "getPlatformVersion") {
result.success("OpenHarmony "+deviceInfo.distributionOSVersion)
}
-
toast
if(call.method=='toast') {
let str:string=call.argument('param') as string;
console.log("str-- > "+str);
prompt.showToast({
message:str
})
}
这里需要注意我们flutter 端 是通过map传递参数给我们鸿蒙next端的
@override
toast(String str) async {
Map<String,dynamic>user={
'param':str
};
await methodChannel.invokeMethod<String>('toast',user);
}
-
完整插件原始鸿蒙next代码
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端插件代码实现
我们先再插件父类抽象类里面 定义我们跟原生端交互的方法
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 类里面实现这些方法
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 端
@visibleForTesting
final methodChannel = const MethodChannel('demoplugin');
-
鸿蒙原生端
onAttachedToEngine(binding: FlutterPluginBinding): void {
this.channel = new MethodChannel(binding.getBinaryMessenger(), "demoplugin");
this.channel.setMethodCallHandler(this)
}
-
然后我们定义 Demoplugin 定义对应的对外方法 给我们的 example 调试工程调用
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系统版本号调用
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调用
@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 使用flutter的版本和鸿蒙使用的不同应该怎么处理

-
回答
使用flutter开发鸿蒙应用使用到的flutter sdk 并不是Google官方适配, 是社区适配的鸿蒙突击队适配的 目前已经适配的
flutter sdk 版本有3.7.12 3.22 3.25等等版本 需要开发使用fvm来个管理自己flutter sdk版本来适配鸿蒙next
-
问题二
使用flutter 框架开发出来的鸿蒙app 体积都很大这个该怎么优化
-
回答
因为flutter 是基于skia引擎运行的自绘制的ui 框架 在打包的时候里面有c++ 代码打包成so 文件被打进鸿蒙hap里面 其实这个在其他平台也有类似的情况 安卓和ios的应用使用flutter开发出来包体积也很大。 如果想要压缩体积可以 考虑只打包针对64位的so文件来处理优化
-
问题三 这是社区的开发者的问题

如果我已经有一个 Flutter 项目,想快速适配鸿蒙,大概需要改多少代码?
-
回答
这个需要看2个方面
第一个看你项目使用的flutter sdk 版本, 如果不是已经适配鸿蒙版如下版本 (3.7.12 3.22 3.25) 等版本 那么工作量会大一点
如果现有的flutter项目跟社区已经适配鸿蒙的flutter sdk版本 有出入那么修改量工作量会比较大
第二个是看你现有flutter的项目里面使用三方库 是否已经鸿蒙化 如果没有鸿蒙化那么需要自己使用channel 去桥接
交互实现 这个过程代码和原始交互代码工作量会大一点这个修改 和鸿蒙原生交互的量 对比和flutter和Android原生交互 的量 是差不多的 UI方面flutter跑在 安卓 iOS 的差异并不大
-
活动感受
这次活动来的人员特别多 ,底下来参加活动同学也是 非常踊跃的发言,把他们在工作和实战遇到的使用flutter跨平台框架开发纯血鸿蒙的 问题和顾虑的点和老师做了一个深入沟通和交流。也希望他们能有收获,也希望后续能多举办类似的活动让老师和开发者们共同成长,共创未来。
学员领取活动礼物

最后总结
这次1024活动感谢官方和51cto ,对我技术的和能力认可,也希望官方后面能多举办类似的活动,让更多老师和开发者们能面对面沟通和交流把开发工作中遇到各种各样问题和想法 畅所欲言,让各自都能成长 技术更上一层楼。最后也预祝鸿蒙生态越来越完善。
-
1024
2025 鸿蒙开发者1024专场
深圳站圆满举行
鸿蒙开发,学无止境!
码到成功,码向未来!























遥遥领先~~~~~~
大牛呀!