Flutter開發進階:Channel 1.初始化路由傳值 2.MethodChannel通信 3.Channel 4.Flutter引擎源碼

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:-]
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章