開發集成環境
[✓] 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) } }