前言

Flutter目前还不稳定,git上目前还有**5000+**的问题没有解决,所以入坑需谨慎啊

背景

在做Android和flutter的混编,混编教程可参考上一篇 Flutter与Android的混编 我们项目在flutter的开发中 引入了 相机相册框架 Image_picker ,二维码扫描 barcode_scan ,还有阿里的 flutter_boost路由框架(这个框架有很多的坑),还有一些其他框架就不介绍了! 其实就目前我来说,这些框架都是坑,在flutter项目上没有什么问题,但是一混编就完蛋了,各种问题,而且你要是网上找答案,资料很少,(拖他的福,我最近英语功力突飞猛进orz…,希望慢慢变好吧)这里简单介绍下:
先说明一下啊,flutter的很多问题可以通过升级flutterSDK到最新版本,flutter插件升级到最新版本去解决(然而混编不行 -_-);混编的话你如果使用了AndroidX 则一些支持库需要统一处理(androidX与flutter兼容有问题)

  1. Image_picker
    与Android混编的时候,首先的一个限制就是版本问题,现在最新的版本是0.6.0+9,在flutter项目里面编译一切正常,但是一混编,就会提示你 :

    This version of image_picker will break your Android build if it or its dependencies

    很明显版本问题,然后就开始降版本,结果都不行,最后查资料 0.4.12+1 这个版本可以运行,,NMMP…确实可以编译了(真特么奇葩);好了这个bug解决了,然后运行 成功,打开相机 一切OK,然后拍照,返回的数据是NULL,what?然后再启动 启动不了了,提示:
    PlatformException(already_active, Image picker is already active, null)
    相机已经运行了,但是就是看不到界面,一开始查资料说是权限的问题,我目标版本是26然后我加了动态获取权限,或者改到22都不行,其实image_picker插件做了权限方面的处理操作,在混编中 插件都会生成对应的 library,例如:
    其中在ImagePickerDelegate 中做了权限的相关处理,这个问题纠结了我很久,查了N多的方案,改配置,改插件里面的代码(混编有个好处就是可以修改插件生成的代码),添加 onActivityResult,然而都不行,曾经把咸鱼的flutter文档都翻了一个遍(本人水平有限,很多高大尚的东西看不懂),然并卵啊,(我们老大就是看着咸鱼用了flutter就让我们也用-_----),当然 目前依然没有解决(别打我—),如果有解决可以通知我,我学习下姿势!

2.barcode_scan
这个插件的问题更多,版本问题,然后我的项目中已经有了zxing的扫描包,然后这两个会起冲突,因为barcode_scan中引入了一个第三方,而这个第三方又引入了ZXing,就算删掉本地的引用也不行,所以就废弃不用啦…手动笑脸
3. cached_network_image
这是一个图片资源的缓存插件,这个里面也有坑(针对AndroidX),他引用了flutter的一个插件flutter_cache_manager,而这个插件里面又引入了 path_provider 插件,而AndroidX支持path_provider版本为最高path_provider: 0.4.1,你如果直接引入这个版本也会报错,所以只能修改flutter_cache_manager的版本,我试了很多版本最高0.5.1可以使用
关于flutter插件与AndroidX兼容版本可以参考该链接
以上的问题,ios没有遇到,只要Android遇到了,,呵呵呵,,是不是使用姿势有问题啊,不得而知…
饭可以不吃,app不能不上线啊,手动 笑着哭
总有方法可以完成任务的,插件不行我就手动调用原生,who 怕 who!

解决办法: Flutter与Native数据交互

  1. Flutter APP同iOS&Android native之间的数据通信如下图所示(手动盗图)

    消息和响应是异步传递,以确保用户界面保持响应。
    在客户端,MethodChannel(API)允许发送对应于方法调用的消息。在平台端,Android上的MethodChannel(API)和iOS上的FlutterMethodChannel(API)支持接收方法调用并返回结果。
    2.平台信道数据类型支持和编解码器
    3. flutter dart代码里添加
  MethodChannel platform;  @override  void initState() {    platform = const MethodChannel('sample.flutter.io/camera');    platform.setMethodCallHandler(methodHandler);    super.initState();  }  // 接收原生平台的方法调用处理  Future methodHandler(MethodCall call) async {    switch (call.method) {      case "action1":        break;    }  }

首先是约定好双方通信的 通道,在这里是标识(sample.flutter.io/camera)。
同时设置好原生调用flutter的方法处理 methodHandler
flutter 调用Android原生的代码如下

  _getCamera() async {    String result;    try {      result = await platform.invokeMethod('getCamera', "2");    } on PlatformException catch (e) {      result = "Failed to  openCamera";    }    setState(() {      _imgPath = new File(result);    });  }

await platform.invokeMethod(‘getCamera’, “2”); 这个方法就是调用原生的处理,加上await 会有返回值,第一个参数用来做标识,第二个作为参数传递

在Android端:

    private lateinit var mChannel: MethodChannel    private fun inintListener() {        mChannel = MethodChannel(flutterView, "sample.flutter.io/camera")        mChannel.setMethodCallHandler { methodCall, result ->            this@FlutterPageActivity.result = result            when (methodCall.method) {                "getBatteryLevel" -> {                    val args = methodCall.arguments()                    Log.e("tag", args)                    val batteryLevel = getBatteryLevel()                    if (batteryLevel != -1) {                        result.success(batteryLevel)                    } else {                        result.error("UNAVAILABLE", "Battery level not available.", null)                    }                }                "getCamera" -> {                    val arg = methodCall.arguments()                    Log.e("tag", arg)                    if (arg == "1")                        uploadPictures(1)                    else                        uploadPictures(2)                }            }        }    }

这里的代码是用来监听回调的,当 dart 调用invokeMethod这里会被触发
三、总结

其实总结下来,flutter调用Android原生代码就一下四点

1.flutter端创建一个MethodChannel,名字要和Android端的相同,并使用MethodChannel通过唯一方法名对应调用Android原生方法。
2.Android端同样生成一个MethodChannel,名字要和上步骤Flutter中创建的相同。继承MethodCallHandler方法后实现onMethodCall(MethodCall call, Result result)方法,通过call拿到上步骤调用的唯一方法名实现不同的方法。
3.在继承了FlutterActivity的Activity中注册步骤2中实现了MethodCallHandler的通道。
4. 开始在flutter的控件中调用原生方法。

写的比较简单,是以完成项目目前的功能为前提下匆匆记录的,希望能帮助到一些人。

更多相关文章

  1. android Frame动画概述+示例
  2. android截图事件监听
  3. Android之最简单的ImageView加边框方法
  4. 图解Android:Touch事件传递机制
  5. Android(安卓)gallery 3D效果
  6. Android官方数据绑定框架DataBinding
  7. Android事件分发机制及源码分析
  8. Android的五大基本组件
  9. Android中使用广播机制退出多个Activity

随机推荐

  1. MySQL使用LOAD_FILE()函数方法总结
  2. mysql 8.0.15 下载安装详细教程 新手必备
  3. Centos7下mysql 8.0.15 安装配置图文教程
  4. Linux下mysql 8.0.15 安装配置图文教程以
  5. sql与各个nosql数据库使用场景的讲解
  6. MySQL group by对单字分组序和多字段分组
  7. MySQL开发规范与使用技巧总结
  8. pycharm2017实现python3.6与mysql的连接
  9. MySQL执行状态的查看与分析
  10. Mysql覆盖索引详解