一. flutter與iOS的消息傳遞
Flutter
和原生交互主要通過channel
進(jìn)行通信猾浦,主要包括三類(以flutter開頭的類均是原生端類)
Flutter | iOS |
---|---|
BasicMessageChannel |
FlutterBasicMessageChannel |
MethodChannel |
FlutterMethodChannel |
EventChannel |
FlutterEventChannel |
下面以MethodChannel
和FlutterMethodChannel
為例進(jìn)行說明
1. flutter端
//1.初始化channel
final platform = const MethodChannel('samples.flutter.io/test');
//2.設(shè)置回調(diào)方法
void initState() {
super.initState();
platform.setMethodCallHandler(invokeFlutterMethod);
}
Future< Null > invokeFlutterMethod(MethodCall call) async{
setState(() {
content = call.arguments['text'];
});
}
//3.在合適的地方(按鈕點(diǎn)擊事件)槽片,調(diào)用iOS方法
Future _invokeIOSMethod() async {
try {
await platform.invokeMethod('invokeIOSMethod',{'text':'flutter傳過來的參數(shù)'});
} on PlatformException catch (e) { }
}
2.iOS端
//1.初始化FlutterViewController頁面(官方推薦方式)
FlutterEngine *flutterEngine =
((AppDelegate *)UIApplication.sharedApplication.delegate).flutterEngine;
FlutterViewController *flutterVC =
[[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
flutterVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:flutterVC animated:YES completion:nil];
//2.初始化channel
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"samples.flutter.io/test"
binaryMessenger:flutterVC.binaryMessenger];
//3.調(diào)用Flutter方法
[channel invokeMethod:@"invokeFlutterMethod" arguments:@{@"text":@"ios傳給flutter的參數(shù)"}];
//4.設(shè)置回調(diào)(等待Flutter調(diào)用)
[channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
if ([call.method isEqualToString:@"invokeIOSMethod"]) {
[flutterVC dismissViewControllerAnimated:YES completion:nil];
}
}];
二.在iOS端切換flutter頁面
?閃退?返回控制器不銷毀随橘?內(nèi)存泄漏?
?解決方案:
官方人員(Dan Field)給出了答案
通過驗(yàn)證官方的例子锦庸,現(xiàn)總結(jié)如下:
1. 使用setInitialRoute
設(shè)置flutter
頁面
自己的理解:重新初始化FlutterViewController
內(nèi)部會重新創(chuàng)建FlutterEngine
机蔗,導(dǎo)致flutter的代碼重新加載main
函數(shù),然后通過window.defaultRouteName
獲取新的路由值(這里路由值為full
)甘萧,根據(jù)路由值加載對應(yīng)頁面
//FullScreenViewController繼承自FlutterViewController
FullScreenViewController *flutterViewController =
[[FullScreenViewController alloc] init];
[flutterViewController setInitialRoute:@"full"];
//在交互的過程中萝嘁,官方代碼動畫過度都設(shè)置的NO,說是有問題扬卷,猜測是過渡不自然牙言,
[self.navigationController
pushViewController:flutterViewController
animated:NO];
2.使用全局的FlutterEngine
設(shè)置flutter
頁面
實(shí)現(xiàn)過程:使用一個(gè)全局的channel
來管理頁面切換,iOS
通過發(fā)送channel
回調(diào)來改變flutter
頁面怪得,如:[[self reloadMessageChannel] sendMessage:@"full"];
咱枉,具體看官方代碼
自己的理解:下面第一行代碼這種設(shè)置路由純屬多余卑硫,雖然路由值設(shè)置成功了(這里只能說是路由值,具體的路由頁面可不一定切換成功了)蚕断,因?yàn)橛玫氖侨?code>FlutterEngine獲取的FlutterViewController
欢伏,此時(shí)是不加載flutter
的main
函數(shù)的。這種情況要想切換頁面必須通過channel
進(jìn)行回調(diào)flutter
端切換路由頁面的方法亿乳。所以我覺得下面的第一行代碼純屬多余硝拧,即使注釋掉也不影響。暫且把它當(dāng)作通過FlutterEngine
設(shè)置路由值的一種方法吧风皿。
[[self engine].navigationChannel invokeMethod:@"setInitialRoute"
arguments:@"full"];
[[self reloadMessageChannel] sendMessage:@"full"];
FullScreenViewController *flutterViewController =
[[FullScreenViewController alloc] initWithEngine:[self engine]
nibName:nil
bundle:nil];
[self.navigationController
pushViewController:flutterViewController
animated:NO]; // Animating this is problematic.
??直接使用 FlutterViewController
河爹,在連續(xù)返回然后進(jìn)入的操作下可能會閃退,建議在 FlutterViewController
消失的情況下執(zhí)行以下代碼
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isMovingFromParentViewController) {
// Note that if we were doing things that might cause the VC
// to disappear (like using the image_picker plugin)
// we shouldn't do this. But in this case we know we're
// just going back to the navigation controller.
// If we needed Flutter to tell us when we could actually go away,
// we'd need to communicate over a method channel with it.
[self.engine setViewController:nil];
}
}
-
附加知識點(diǎn)
- 常量構(gòu)造函數(shù)的作用桐款?
理解:const
修飾的構(gòu)造函數(shù)咸这,要求成員變量必須都是final
的,并且在構(gòu)造函數(shù)中要初始化
在類內(nèi)部修飾const
如果修飾成員變量魔眨,必須和static
配合使用
class Hello {
const Hello(this.name,this.age);
final String name;
final int age;
}