26 | 如何在Dart层兼容Android/iOS平台特定实现?(一)
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Flutter的方法通道(Method Channel)机制为Dart和原生代码之间的交互提供了便捷的方式,使得Flutter应用能够轻松访问Android和iOS平台的底层能力。通过方法通道,Flutter可以调用原生系统底层能力和代码库,实现诸如数据持久化、推送、摄像头硬件调用等功能。本文通过示例展示了在Flutter中实现与原生代码的交互,包括发起方法调用请求、在Android和iOS平台上完成对应的接口实现,以及处理和响应方法调用请求的过程。此外,还介绍了在不同平台间的常见数据类型转换。这些内容有助于开发者理解Flutter的跨平台特性和与原生代码的交互方式。方法通道解决了逻辑层的原生能力复用问题,使得Flutter能够通过轻量级的异步方法调用,实现与原生代码的交互。需要注意的是,方法通道是非线程安全的,因此所有接口调用必须发生在主线程。文章最后提出了一个思考题,鼓励读者扩展方法通道示例,支持传入AppID和包名,以实现跳转到任意一个App的应用市场。这篇文章内容丰富,对于想要深入了解Flutter与原生代码交互的开发者来说,是一篇值得阅读的技术文章。
《Flutter 核心技术与实战》,新⼈⾸单¥59
全部留言(17)
- 最新
- 精选
- 和小胖思考题: flutter 端: // 处理按钮点击 handleButtonClick() async { int result; // 异常捕获 try { // 异步等待方法通道的调用结果 result = await platform.invokeMethod('openAppMarket', <String, dynamic>{ 'appId': "com.xxx.xxx", 'packageName': "xxx.com.xxx", }); } catch (e) { result = -1; } print("Result:$result"); } Android 端: if (call.method == "openAppMarket") { if (call.hasArgument("appId")) { //获取 appId call.argument<String>("appId") } if (call.hasArgument("packageName")) { //获取包名 call.argument<String>("packageName") } }
作者回复: 厉害👍
2019-10-146 - 矮个子先生😝看了下Flutter提供的api,动手实现了下,native调flutter的方法 Future<String> nativeCallFlutter(int a) async { print('success $a'); return 'success'; } platform.setMethodCallHandler((MethodCall call) async { if (call.method == 'nativeCallFlutter') { return await nativeCallFlutter(call.arguments); } return 'none'; }); 在iOS端调用: [channel invokeMethod:@"nativeCallFlutter" arguments:@1 result:^(id _Nullable result) { NSLog(@"result = %@",result); }];
作者回复: 赞,方法通道是双向的,既支持Dart调Native,也支持Native调Dart。第31节会讲具体的实践
2019-08-274 - 寂寞不点烟而原生代码在处理方法调用请求时,如果涉及到异步或非主线程切换,需要确保回调过程是在原生系统的 UI 线程(也就是 Android 和 iOS 的主线程)。在Android中UI现线程不一定是主线程。
作者回复: 看怎么理解,如果你理解能操作UI的线程就是UI线程,那UI线程确实不一定是主线程
2019-12-101 - 菜头如果是获取系统相册直接获取 图片对象 Dart 支持各个平台的 image 对象类型吗
作者回复: 这种建议只在原生实现界面,flutter接受最后选择的图片地址
2019-11-03 - 辉哥问一下,Flutter和原生应用应该不处于同一个进程吧
作者回复: 不特殊处理的话,是一个进程
2019-09-24 - 江宁彭于晏// 声明 MethodChannel const platform = MethodChannel('samples.chenhang/utils'); // 处理按钮点击 handleButtonClick(Map paramDic) async{ int result; // 异常捕获 try { // 异步等待方法通道的调用结果,Map 中插入appid和包名,跳转链接等信息 result = await platform.invokeMethod('openAppMarket', [paramDic]); } catch (e) { result = -1; } print("Result:$result"); }
作者回复: 这个接口的易用性貌似不太合理啊,调用方和原生代码宿主对于参数的处理都比较别扭
2019-09-11 - 小水滴iOS系统创建多份FlutterViewController会有什么问题吗
作者回复: 每启动一个 FlutterVC实例,就会创建一套新的渲染机制,即 Flutter Engine,以及底层的 Isolate。这些实例之间的内存是不互相共享的,系统资源消耗比较大
2019-08-30 - ptlCodermethodChannelWithName:@"samples.chenhang/utils" 这个通道名称有什么要求嘛?还是说见名知意就好? 另外,如果flutter很多地方都用到了原生系统方法,岂不是在iOS或安卓flutter入口那做很多个判断?
作者回复: 1.没要求,主要Dart层与原生宿主层保持一致就可以; 2.对
2019-08-29 - 许童童dart层通过platform.invokeMethod 第二个参数传入动态参数 native层可以通过call.argument拿到参数
作者回复: 赞
2019-08-27 - 宇dart层: platform.invokeMethod('openAppStore', {"appId": "com.tencent.mm"}); native层: String appId = call.argument("appId"); try { Uri uri = Uri.parse("market://details?id=" + appId); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } catch (Exception e) { result.error("UNAVAILABLE", "没有安装应用市场", null); }
作者回复: 赞
2019-08-27