1.Flutter和原生代码的通信
我们只用Flutter实现了一个页面,现有的大量逻辑都是用Java实现,在运行时会有许多场景必须使用原生应用中的逻辑和功能,例如网络请求,我们统一的网络库会在每个网络请求中添加许多通用参数,也会负责成功率等指标的监控,还有异常上报,我们需要在捕获到关键异常时将其堆栈和环境信息上报到服务器。这些功能不太可能立即使用Dart实现一套出来,所以我们需要使用Dart提供的Platform Channel功能来实现Dart→Java之间的互相调用。
以网络请求为例,我们在Dart中定义一个MethodChannel对象:
import'dart:async'; import'package:flutter/services.dart'; constMethodChannel_channel=constMethodChannel('com.kuaiX.happy/getVersion'); Future<Map<String, dynamic>>post(Stringpath, [Map<String, dynamic>form]) async { return_channel.invokeMethod("getVersion", {'path': path, 'body': form}).then((result) { returnnewMap<String, dynamic>.from(result); }).catchError((_) =>null); } 然后在Java端实现相同名称的MethodChannel:publicclassFlutterNetworkPluginimplementsMethodChannel.MethodCallHandler { privatestaticfinalStringCHANNEL_NAME="com.kuaiX.happy/getVersion"; publicvoidonMethodCall(MethodCallmethodCall, finalMethodChannel.Resultresult) { switch (methodCall.method) { case"getVersion": RetrofitManager.performRequest(post((String) methodCall.argument("path"), (Map) methodCall.argument("body")), newDefaultSubscriber<Map>() { publicvoidonError(Throwablee) { result.error(e.getClass().getCanonicalName(), e.getMessage(), null); } publicvoidonNext(MapstringBaseResponse) { result.success(stringBaseResponse); } }, tag); break; default: result.notImplemented(); break; } } } 在Flutter页面中注册后,调用post方法就可以调用对应的Java实现:loadData: (callback) async { Map<String, dynamic>data=awaitgetVersion("version/level"); if (data==null) { callback(false); return; } _data=AllCategoryResponse.fromJson(data); if (_data==null||_data.code!=0) { callback(false); return; } callback(true); }),
2.Demo实现 -> 从原生传数据到FLutter端
classAppUtils : FlutterPlugin, MethodCallHandler { privatevarchannel: MethodChannel?=nullprivatevarsContext: Context?=nullprivatevalTAG="AppUtils"overridefunonAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { channel=MethodChannel(binding.getBinaryMessenger(), TAG) channel?.setMethodCallHandler(this) sContext=binding.getApplicationContext() } overridefunonDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { channel?.setMethodCallHandler(null); } overridefunonMethodCall(call: MethodCall, result: MethodChannel.Result) { if (sContext==null) { throwRuntimeException(" context is null please call setContext(this) in Application.onCreate()") } if (call.method.equals("getPlatformVersion")) { result.success("Android "+android.os.Build.VERSION.RELEASE); } elseif (call.method.equals("getSmid")) { } else { result.notImplemented(); } } }
Flutter端实现classHomeLogicextendsGetMaterialController { staticconstMethodChannelchannel=constMethodChannel('AppUtils'); staticFuture<String?>getPlatformVersion() async { finalString?version=awaitchannel.invokeMethod('getPlatformVersion'); returnversion; } onInit(){ String?temp=awaitgetPlatformVersion(); print("12i3904201"+temp.toString()); } }