1.初始化路由傳值
//ios
let vc = FlutterViewController()
vc.setInitialRoute("openCompany")//設置爲one
self.navigatonController?.present(vc, animated:true)
//flutter
void main() => runApp(MyApp(pageIndex:window.defaultRouteName));
class MyApp extends StatelessWidget {
final String pageIndex;//接收到openCompany
const MyApp({Key? key, required this.pageIndex}) : super(key:key);
Widget build(BuildContext context){
//根據pageIndex去加載頁面
return ...
}
}
- 是單向的,只能App給flutter傳遞,導致頁面不能關閉。
2.MethodChannel通信
//ios
let engine = FlutterEngine(name: "app")
var flutter : FlutterViewController? = nil
override func viewDidLoad(){
engine.run()
self.flutter = FlutterViewController(engine: self.engine, nibName: nil, bundle: nil)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let __flutter = self.flutter {
let channel = FlutterMethodChannel(name: "explorer", binaryMessenger: __flutter.binaryMessenger)
self.present(__flutter, animated: true, completion: nil)
channel.setMethodCallHandler { method, result in
if(method.method == "exit"){
NX.print(method.method)
}
}
channel.invokeMethod("openCompany", arguments:nil);
}
}
//flutter
void main() => runApp(MyApp());
class MyApp extends StatefullWidget {
const MyApp({Key? key});
MyAppState createState() => MyAppState()
}
class MyAppState extends State<MyApp> {
const channel = MethodChannel("explorer");
String pageIndex;//接收到openCompany
void initState(){
channel.setMethodCallHandler((call){
pageIndex = call.method;//openCompany
setState({});
});
}
Widget build(BuildContext context){
//根據pageIndex去加載頁面
//響應事件
{
channel.invokeMapMethod("exit", {});
}
return ...
}
}
- FlutterEngine模式下setInitialRoute失效
3.Channel
1.FlutterMethodChannel
傳遞方法的,方法調用(案例如上)
2.FlutterBasicMessageChannel
持續通信,收到消息後還可以恢復
//ios
let channel = FlutterBasicMessageChannel(name: "explorer", binaryMessenger: __flutter.binaryMessenger)
channel.setMessageHandler { value, reply in
//收到來自flutter的消息
}
channel.sendMessage("----")//發送給flutter的消息
//flutter
BasicMessageChannel channel = BasicMessageChannel("explor", StandardmessageCodec());
channel.setMessageHandler((message){
//來自App的消息
});
channel.send("-----")//發給App的消息
3.EventChannel
數據流
4.Flutter引擎源碼
https://blog.csdn.net/dongzhong1990/article/details/105678124
源碼主要分爲兩部分:
Flutter官方源碼下載路徑:
engine: https://github.com/flutter/engine
flutter framework: https://github.com/flutter/flutter
- Engine,是可供Flutter宿主應用提供的一個可移植運行時。Engine實現了Flutter的核心庫,包括動畫、圖形、文件、網絡I/O、訪問支持、插件架構和Dart的運行時、編譯工具鏈;
- Flutter Framework,大部分的Flutter開發者主要通過Flutter Framework交互。Framework提供了一個現代的、可交互的框架,以及一個豐富的平臺、佈局、基礎部件的集合。
1.channel通信原理
1.1.MethodChannel通信
let channel = FlutterMethodChannel(name:"explorer", binaryMessenger: self.flutterViewController.binaryMessenger)
初始化方法:將如下三個信息保存起來
- name:channel名稱
- binaryMessenger:消息管理器
- codec:解碼器(上層傳空時下層會自動調用單例)
channel.setMethodCallHandler { method, result in
if(method.method == "exit"){
}
}
設置消息回調:判斷handler是否爲空,來進行歷史數據的清空和重新賦值。
- handler:最終毀掉到上層的一個句柄
- 內部會自己定義一個messageHandler,用來接收最下層的回調,並且可以把消息拋到最上層。
- 內部會將新定義的channel.name和messageHandler用key-value的形式保存起來。
channel.invokeMethod("openDetail", arguments: nil, result: {})
- 通過channel.name找到dart部分的消息回調,然後執行handler big你就愛哪個數據傳遞過去
2.解碼器
三種channel有2種解碼器,解碼器實際上是一種數據轉換協議,iOS、Android、dart三端通用。
2.1.FlutterMessageCodec
@protocol FlutterMessageCodec
+ (instancetype)sharedInstance;
- (NSData * _Nullable)encode:(id _Nullable)message;
- (id _Nullable)decode:(NSData * _Nullable)message;
@end
2.2FlutterMethodCodec
服務Methodchannel、EventChannel
@protocol FlutterMethodCodec
+ (instancetype)sharedInstance;
- (NSData *)encodeMethodCall:(FlutterMethodCall *)methodCall;
- (NSData *)decodeMethodCall:(NSData *)methodCall;
- (NSData *)encodeSuccessEnvelope:(id _Nullable)result;
- (NSData *)encodeErrorEnvelope:(FlutterError *)error;
- (id _Nullanle)decodeEnvelope:(NSData *)envelope;
@end
2.3 FlutterStandardReaderWriter
- FlutterStandardReader
- (nullable id)readValue {
//
[self readValueOfType:[self readByte]]
}
- (nullable id)readValueOfType:(UInt8)type{
}
- FlutterStandardWriter
- (void)writeValue:(id)value {
//判斷類型
//寫入標誌位(數據類型)+數據本身
[- writeByte:]
[- writeBytes:- length:-]
}