开发集成环境
[✓] Flutter (Channel stable, v1.12.13+hotfix.9, on Mac OS X 10.14.6 18G103, locale zh-Hans-CN)
一、简述Flutter集成到Android原生项目
二、Android原生以AAR形式集成Flutter项目
三、Flutter与原生(Android/IOS)的消息通信
四、Flutter中如何使用原生控件/组件
五、Flutter状态管理Provider与Redux
六、Flutter升级及开发中遇到的问题汇总
前面也谈到除了一些新项目以外,目前大多数都是在原有项目中逐步插入跨平台技术,虽说Flutter提供的插件越来越丰富,但在新项目中的需求也会或多或少涉及到原生的帮助,自然而然又稍微掺杂点混编了。
其实跨平台框架在与原生项目进行混编时,是避免不了两者之间的相互通信,当然也会涉及到对应的页面跳转,仔细想想其实当解决了两者之间的相互通信后,好像页面跳转也不是什么大问题了,只是方式的友好与否而已。
下面分别就Flutter与Android消息通信、Flutter与IOS消息通信两个方面作下简单描述,其中Flutter与Android消息通信涉及
Java与Kotlin
两种语言、Flutter与IOS消息通信涉及Object-C和Swift
两种语言。
一、Flutter与Android的消息通信
1、Android端实现接收消息和发送消息
-
Java版
public class MainActivity extends FlutterActivity { @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); MethodChannel mc = new MethodChannel(flutterEngine.getDartExecutor(), "com.cc.flutter.native"); //此处名称应与Flutter端保持一致 //接收Flutter消息 mc.setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { System.out.println("MethodChannel call.method:"+call.method+ " call arguments:"+call.arguments); switch (call.method){ case "envType": result.success("2"); break; case "toast": String msg = call.argument("msg"); Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); result.success("成功啦"); break; default: result.error("404", "未匹配到对应的方法"+call.method, null); } } }); // mc.invokeMethod("aaa", "c") //发送消息 } }
-
Kotlin版
class MainActivity : FlutterActivity(){ override fun configureFlutterEngine(flutterEngine: FlutterEngine) { var methodChannel = MethodChannel(flutterEngine.dartExecutor, "com.cc.flutter.native") methodChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result? -> println("MethodChannel call.method:" + call.method + " call arguments:" + call.arguments) when (call.method) { "envType" -> result!!.success("2") "toast" -> { val msg = call.argument<String>("msg") showToast(msg!!) result!!.success("成功啦") } else -> result!!.error("404", "未匹配到对应的方法" + call.method, null) } } } }
2、Flutter测试实现发送消息和接收消息
class NativeUtils{
static const String NATIVE_CHANNEL_NAME = "com.cc.flutter.native"; //给native发消息,此处应和客户端名称保持一致
//channel_name每一个通信通道的唯一标识,在整个项目内唯一!!!
static const _channel = const MethodChannel(NATIVE_CHANNEL_NAME);
///
/// @Params:
/// @Desc: 获取native的数据
///
static getNativeData(key,[ dynamic arguments ]) async{
try {
String resultValue = await _channel.invokeMethod(key, arguments);
return resultValue;
}on PlatformException catch (e){
print(e.toString());
return "";
}
}
static registerMethod(){
//接收处理原生消息
_channel.setMethodCallHandler((handler) {
switch (handler.method) {
case "aaa":
// 发送原生消息
_channel.invokeMethod("toast", {"msg": "您调用了dart里的方法"});
break;
}
});
}
}
- 在Flutter页面初始化时调用
NativeUtils.registerMethod()
后,这样客户端调用methodChannel.invokeMethod("aaa", "c")
此时Flutter才能收到对应的消息。 - 在Flutter页面中调用
NativeUtils. getNativeData("envType")
此时才能调用原生客户端对应的方法获取数据。
以上是Flutter与Android端相互通信的部分,下面部分是Flutter与IOS相互通信的部分。
二、Flutter与IOS的消息通信
1. Android端实现接收消息和发送消息
-
Object-C版
#import "AppDelegate.h" #include "GeneratedPluginRegistrant.h" #import "FlutterNativePlugin.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"com.cc.flutter.native" binaryMessenger:controller.binaryMessenger]; [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if ([call.method isEqualToString:@"cityId"]) { result([NSNumber numberWithInt:1]); } if([call.method isEqualToString:@"envType"]){ result(@"1"); } else { result(FlutterMethodNotImplemented); } }]; return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end
-
Swift版
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) let controller:FlutterViewController = window.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: "com.cc.flutter.native", binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { (call, result) in if "cityId" == call.method{ result(1); } else if "envType" == call.method{ result("1"); } else{ result(FlutterMethodNotImplemented) } } return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }