混合开发与引擎¶
Flutter项目调用原生的功能(相机,相册)¶
通讯¶
MethodChannel¶
主要传递方法调用,一次通讯
methodChannel调用invokeMethod:发送消息
methodChannel调用setMethodCallHandler:设置回调
flutter
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_demo/widgets/scaffold_demo.dart';
class MethodChannelDemo extends StatefulWidget {
const MethodChannelDemo({Key? key}) : super(key: key);
@override
State<MethodChannelDemo> createState() => _MethodChannelDemoState();
}
class _MethodChannelDemoState extends State<MethodChannelDemo> {
File? _avatarFile;
final MethodChannel _methodChannel = const MethodChannel('mine_page/method');
@override
void initState() {
// TODO: implement initState
super.initState();
_methodChannel.setMethodCallHandler((call) {
if (call.method == 'imagePath') {
print(call.arguments);
String imagePath = call.arguments.toString().substring(7);
setState(() {
_avatarFile = File(imagePath);
});
}
return Future(() {});
});
}
@override
Widget build(BuildContext context) {
return HHScaffold(
Center(
child: //头像
GestureDetector(
onTap: () {
_methodChannel.invokeMapMethod('picture'); //通知原生
},
child: Container(
width: 70,
height: 70,
//圆角
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
image: DecorationImage(
image: _avatarFile == null
? const AssetImage('images/Hank.png') as ImageProvider
: FileImage(_avatarFile!),
//裁剪
fit: BoxFit.cover)),
),
),
),
title: 'channel',
);
}
}
iOS
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
@property (nonatomic, strong)FlutterMethodChannel *methodChannel;
@end
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
//注册方法 flutter和原生交互
FlutterViewController *vc = (FlutterViewController *)self.window.rootViewController;
self.methodChannel = [FlutterMethodChannel methodChannelWithName:@"mine_page/method" binaryMessenger:vc];
UIImagePickerController *imageVC = [[UIImagePickerController alloc]init];
imageVC.delegate = self;
[self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
if ([call.method isEqualToString:@"picture"]) {
[vc presentViewController:imageVC animated:YES completion:nil];
}
}];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
[picker dismissViewControllerAnimated:YES completion:^{
NSString *imagePath = [NSString stringWithFormat:@"%@",info[@"UIImagePickerControllerImageURL"]];
[self.methodChannel invokeMethod:@"imagePath" arguments:imagePath];
}];
}
@end
BasicMessageChannel¶
持续通讯,收到消息之后还可以回复消息。
EventChannel¶
数据流 持续通讯
创建:Channel构造方法有name,
发:invoke方法名,
接收回调:setMethodCallHandler,setMessageHandler
混合工程自动化¶
工程自动化重点是写脚本。
flutter工程,iOS工程,android工程。不需要配置环境。
混合工程一般单独的工程,flutter是module,iOS也有一个native工程。
混合开发 原生项目嵌入Flutter¶
AS创建Flutter Module
。
.android
和.ios
是隐藏文件,调试用的,里面不要写代码,不会打包进去。
1、原生有flutter环境¶
比较重,不建议。有渲染引擎Flutter.framework
也要进内存。
iOS没有flutter,需要使用pod。
Xcode创建工程,pod init
创建pod。
#flutter插件路径
flutter_application_path = '../flutter_module'
# 加载函数 参数1:flutter路径 2:iOS 3:这是flutter工程 4:podhelper.rb
load File.join(flutter_application_path,'.iOS','Flutter','podhelper.rb')
platform :ios, '9.0'
target 'NativeDemo' do
# 安装
install_all_flutter_pods(flutter_application_path)#flutter依赖的库也加载进来
use_frameworks!
# Pods for NativeDemo
end
pod install
之后,native就有了flutter的东西了。
修改了flutter代码,AS编译或者Xcode清空缓存运行。
2、原生没有flutter环境¶
2.1 framework混合开发¶
打包成framework直接给native使用。
-
终端进入flutter module目录
-
flutter build ios-framework --output=../flutter_app
构建混合工程
- Debug调试
- Profile介于发布和调试,既有release性能,又有debug的调试功能。
- Release发布
Flutter.xcframework
和flutter环境有关。
App.xcframework
和自己写的flutter代码页面有关。
多个flutter module只需要一个Flutter.xcframework
,和不同的App.xcframework
。
- 集成framework
2.2 cocoapods混合工程¶
-
终端进入flutter module目录
-
flutter build ios-framework --cocoapods --output=../flutter_app
构建混合工程
- Debug调试
- Profile介于发布和调试,既有release性能,又有debug的调试功能。
- Release发布
Flutter.podspec
和flutter环境有关,从cocoapods上下载。
App.xcframework
和自己写的flutter代码页面有关。
多个flutter module只需要一个Flutter.xcframework
,和不同的App.xcframework
。
-
把文件拖进native工程
-
创建podfile,添加
pod 'Flutter',:podspec => 'Debug/Flutter.podspec'
,然后pod install。 -
配置App.xcframework
flutter只要做了更改,原生就需要更新,需要一个代码仓库,flutter把module开发完之后,代码push,仓库把代码工程打包编译成native使用的framework。
借用GitHub,Actions自己写脚本代码CI就可以实现上面的功能。
引擎¶
下载引擎:https://github.com/flutter/engine
路径不要有中文
三方工作所在目录需要有可执行权限
flutter版本:
➜ ~ flutter channel
Flutter channels:
master//主分支
dev //正在开发
beta //新特性
* stable//稳定版
➜ ~
编译引擎¶
GN构建文件
- 进入路径
路径/engine_download/src/flutter/tools
# iOS
# 真机debug
./gn --ios --unoptimized
# 真机release ( , )
./gn --ios --unoptimized --runtime-mode=release
# 模拟器版本
./gn --ios --simulator --unoptimized
# 主机端(Mac)构建
./gn --unoptimized
Ninja编译
-
先安装ant:
brew install ant
-
进入路径
路径/engine_download/src/out
-
bash ninja -C host_debug_unopt && ninja -C ios_debug_sim_unopt && ninja -C ios_debug_unopt && ninja -C ios_release_unopt