Flutter和原生代码的通信
【摘要】 我们只用Flutter实现了一个页面,现有的大量逻辑都是用Java实现,在运行时会有许多场景必须使用原生应用中的逻辑和功能,例如网络请求,我们统一的网络库会在每个网络请求中添加许多通用参数,也会负责成功率等指标的监控,还有异常上报,我们需要在捕获到关键异常时将其堆栈和环境信息上报到服务器。这些功能不太可能立即使用Dart实现一套出来,所以我们需要使用Dart提供的Platform Channel功
1.Flutter和原生代码的通信
我们只用Flutter实现了一个页面,现有的大量逻辑都是用Java实现,在运行时会有许多场景必须使用原生应用中的逻辑和功能,例如网络请求,我们统一的网络库会在每个网络请求中添加许多通用参数,也会负责成功率等指标的监控,还有异常上报,我们需要在捕获到关键异常时将其堆栈和环境信息上报到服务器。这些功能不太可能立即使用Dart实现一套出来,所以我们需要使用Dart提供的Platform Channel功能来实现Dart→Java之间的互相调用。
以网络请求为例,我们在Dart中定义一个MethodChannel对象:
import 'dart:async';
import 'package:flutter/services.dart';
const MethodChannel _channel = const MethodChannel('com.kuaiX.happy/getVersion');
Future<Map<String, dynamic>> post(String path, [Map<String, dynamic> form]) async {
return _channel.invokeMethod("getVersion", {'path': path, 'body': form}).then((result) {
return new Map<String, dynamic>.from(result);
}).catchError((_) => null);
}
然后在Java端实现相同名称的MethodChannel:
public class FlutterNetworkPlugin implements MethodChannel.MethodCallHandler {
private static final String CHANNEL_NAME = "com.kuaiX.happy/getVersion";
@Override
public void onMethodCall(MethodCall methodCall, final MethodChannel.Result result) {
switch (methodCall.method) {
case "getVersion":
RetrofitManager.performRequest(post((String) methodCall.argument("path"), (Map) methodCall.argument("body")),
new DefaultSubscriber<Map>() {
@Override
public void onError(Throwable e) {
result.error(e.getClass().getCanonicalName(), e.getMessage(), null);
}
@Override
public void onNext(Map stringBaseResponse) {
result.success(stringBaseResponse);
}
}, tag);
break;
default:
result.notImplemented();
break;
}
}
}
在Flutter页面中注册后,调用post方法就可以调用对应的Java实现:
loadData: (callback) async {
Map<String, dynamic> data = await getVersion("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端
class AppUtils : FlutterPlugin, MethodCallHandler {
private var channel: MethodChannel? = null
private var sContext: Context? = null
private val TAG = "AppUtils"
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(binding.getBinaryMessenger(), TAG)
channel?.setMethodCallHandler(this)
sContext = binding.getApplicationContext()
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel?.setMethodCallHandler(null);
}
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
if (sContext == null) {
throw RuntimeException(" context is null please call setContext(this) in Application.onCreate()")
}
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else if (call.method.equals("getSmid")) {
} else {
result.notImplemented();
}
}
}
Flutter端实现
class HomeLogic extends GetMaterialController {
static const MethodChannel channel = const MethodChannel('AppUtils');
static Future<String?> getPlatformVersion() async {
final String? version = await channel.invokeMethod('getPlatformVersion');
return version;
}
@override
onInit(){
String? temp = await getPlatformVersion();
print("12i3904201" + temp.toString());
}
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)