JHHK

欢迎来到我的个人网站
行者常至 为者常成

混合开发

目录

介绍

一、混合开发

flutter application
Flutter应用程序是一个完整的移动应用程序,使用Flutter框架进行开发。它包括了从UI布局到业务逻辑的一切,是最终用户可以下载和使用的产品
开发完整的移动应用程序,可以运行在iOS和Android设备上
包含主函数、应用入口、各种页面、路由、状态管理等

flutter module
Flutter模块是一种可以嵌入到现有的Android或iOS应用中的Flutter代码

flutter package
Flutter包是一组共享的Dart代码库,可以被Flutter应用或其他包使用。它主要用于逻辑和UI组件的复用。

flutter plugin
Flutter插件是一个包含Dart代码和平台特定代码(如Java、Kotlin、Objective-C、Swift)的包。它允许Flutter应用访问平台(iOS和Android)提供的原生功能。

二、目录

Flutter Module
│
├── lib/
├── pubspec.yaml
└── .ios/
      │
      ├── Runner(仅用于编译)
      ├── Podfile
      ├── Flutter.framework
      ├── Plugins
      └── Generated Config

Flutter Module 中 .ios 的真正作用:对于 Flutter Module 来说,可以把它理解成一个构建辅助工程,而不是业务工程。

它主要承担以下职责:
提供一个最小的 iOS 宿主工程,供 xcodebuild 编译 Flutter 和插件。
生成 Flutter 相关配置(如 Generated.xcconfig、podhelper.rb 等)。
管理 Flutter 插件在 iOS 平台的依赖。
为原生工程提供集成入口(例如 podhelper.rb 或生成的 Framework)。

需要强调的是,真正发布到 App Store 的仍然是你的原生 iOS 工程,而不是 .ios 中的 Runner。

执行 flutter clean 会删除.ios目录。
再执行 flutter pub get 会重新生成.ios目录。
.ios目录及其内容是flutter tool按照对应平台的模版自动生成的。
原生工程执行pod install 的时候podhelper.rb等文件会被执行。

三、Flutter Module 必须使用 CocoaPods 吗?
方式一:CocoaPods(最常见,也是官方推荐)
方式二:Swift Package Manager(SPM)
方式三:预编译 Framework(无需 CocoaPods)
Flutter 支持:

flutter build ios-framework

生成

Flutter.xcframework

App.xcframework

shared_preferences.xcframework

path_provider.xcframework

...

然后拖进xcode。

其它

Flutter项目调用原生的某些功能

原生项目里面包含Flutter模块

FlutterViewController 创建再销毁之后会有8M的内存泄露
所以Flutter与原生页面之前不适合来回切换,FlutterViewController应该常驻内存

让flutter给原生传递数据,原生应该提供一个方法让flutter来调用,通过方法的参数把数据传过来
原生调用flutter也是同样的道理

Flutter调用原生

// flutter 侧代码
MethodChannel _methodChannel = MethodChannel('mine_page');
_methodChannel.invokeMapMethod('picture', {"param1":"hehe","param2":10});

//iOS侧代码
FlutterViewController *vc = (FlutterViewController*)self.window.rootViewController;
self.methodChannel = [FlutterMethodChannel methodChannelWithName:@"mine_page" binaryMessenger:vc];

[self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
    if ([call.method isEqualToString:@"picture"]) {
      //如果有返回值,通过result将返回值传递会flutter
      result(xxx)
    }
}];

Flutter SDK 升级

升级
从官网下载下来的SDK,如果直接解压是无法使用的。当执行Flutter –version的时候会提示没有git目录。
所以我们应该从官网clone下来SDK,然后将分支切换到使用的版本的分支。
这个时候,当我们执行pod install的时候会报错,提示我们找不到engine。
这是因为SDK没有给我们提供编译好的engine,需要我们自己编译。
我们需要在自己的flutter module 工程根目录下,执行flutter run,会自动帮我们编译好engin。
此时会在:/Users/lxy/FlutterSDK/flutter/bin/cache/artifacts/engine 目录下找到对应平台的engine

遇到的问题
升级后,执行pod install有两个三方库报头文件找不到的错误。

post_install do |installer|
  installer.pods_project.targets.each do |target|
  
      # 修复 sqflite_darwin: Pods/Headers/Private/sqflite_darwin/SqflitePlugin.h 是符号链接,
      # 其内部 #import "include/sqflite_darwin/SqflitePluginPublic.h" 为相对路径,
      # clang 不跟随符号链接解析相对路径, 导致 FlutterPluginRegistrant 等引用方编译失败.
      # 这里给所有 target 补充指向 sqflite_darwin 真实源码 Sources 目录的搜索路径 (该目录下存在 include/sqflite_darwin/).
      if target.name == "FlutterPluginRegistrant" || target.name == "sqflite_darwin"
        target.build_configurations.each do |config|
          search_path = "${PODS_ROOT}/../../df-flutter/.ios/.symlinks/plugins/sqflite_darwin/darwin/sqflite_darwin/Sources/sqflite_darwin"
          config.build_settings['HEADER_SEARCH_PATHS'] ||= ['$(inherited)']
          config.build_settings['HEADER_SEARCH_PATHS'] << search_path unless config.build_settings['HEADER_SEARCH_PATHS'].include?(search_path)
        end
      end

  end
end
target "df2-ios" do
  # 其它三方库依赖 OrderedSet,编译过程发现 OrderedSet 内部 报找不到头文件的错误。
  # 因为其引用方式为module,所以添加如下配置
  pod 'OrderedSet', :modular_headers => true
end

flutter_flutter

flutter_flutter是 Flutter SDK 的 OpenHarmony 适配版本,基于 Flutter 官方社区 Flutter Version 构建,由 OpenHarmony-Flutter 团队维护。
开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,复用现有 Flutter 生态资源。

针对pub.dev的三方库:
带插件的三方库,同样需要OpenHarmony-Flutter进行鸿蒙适配。
不带插件的纯dart三方库,不需要进行适配,比如:flutter_riverpod。


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.