Android原生项目集成Flutter问题总结(持续更新)

集成环境说明(使用关联源代码方式非aar引用)
  • Window10
  • Android Studio 3.5.3
  • flutter doctor
      D:\workspace>flutter doctor
      Doctor summary (to see all details, run flutter doctor -v):
      [√] Flutter (Channel stable, v1.12.13+hotfix.5, on Microsoft Windows [Version 10.0.17763.914],       
           locale zh-CN)
      [√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
      [√] Android Studio (version 3.5)
      [√] VS Code (version 1.40.2)
      [√] Connected device (1 available)
      ! Doctor found issues in 1 category.
    
问题:编译报错resource android:attr/fontVariationSettings not found.

具体报错信息如下:

Execution failed for task ':app:processDEV_TESTDebugResources'.
> Android resource linking failed
  Output:  D:\workspace\CarMaid\app\build\intermediates\incremental\mergeDEV_TESTDebugResources\merged.dir\values\values.xml:637: error: resource android:attr/fontVariationSettings not found.
  D:\workspace\CarMaid\app\build\intermediates\incremental\mergeDEV_TESTDebugResources\merged.dir\values\values.xml:638: error: resource android:attr/ttcIndex not found.
  error: failed linking references.
  
  Command: ...省略
  Daemon:  AAPT2 aapt2-3.2.1-4818971-windows Daemon #0
  Output:  D:\workspace\CarMaid\app\src\main\res\values\dimens.xml: AAPT: error: resource android:attr/fontVariationSettings not found.
      
  D:\workspace\CarMaid\app\src\main\res\values\dimens.xml: AAPT: error: resource android:attr/ttcIndex not found.
      
  error: failed linking references.
  Command: ...省略
  Daemon:  AAPT2 aapt2-3.2.1-4818971-windows Daemon #0

解决方案:出现该问题的原因是因为原生项目sdk编译版本和flutter的sdk编译版本不一致导致。我本地原生项目compileSdkVersion和targetSdkVersion是27,然后flutter里面的是28。所以我把自己本地的原生项目项目修改成了28,重新编译问题解决。但是目前我不清楚如何去修改flutter module生成时android编译版本,希望知道的同学可以留言告诉我,不胜感激。

问题:flutter页面热重载失效(修改代码后保存提示热重载、重启成功,但是页面没有任何变化)

解决方案:需要先将app杀死,然后执行flutter attach或者使用AS的工具栏按钮。此时,AS底部控制台会出现下方图片状态:

图片1
,然后接着再点击我们的App启动起来进入flutter页面,然后修改代码,保存后会发现flutter页面自动刷新了。这里刚开始有个问题,就是在上一次热重载失败修改了flutter页面,这个时候刚进入flutter页面是不会刷新的,即使你点击热重载、重启按钮都不会更新。这个情况需要你再次修改一下flutter页面,再次保存就会刷新了。

问题:关于使用缓存FlutterEngine如何传递路由问题

现在官方为了提高原生启动flutter页面的速度,建议我们使用缓存FlutterEngine使用它们提供的withCacheEngine()去创建Flutter页面。但是这种方式就会有一个问题就是这种方式是没法传递routeName。也就是说一个cacheId对应一个flutter页面。这种对于如果以后flutter页面多了,对于页面id管理会是一个问题,而且保存过多的FlutterEngine对于内存也是一种负担。所以我有一个想法:原生页面跳转flutter页面通过一个flutter路由页面去统一管理,原生调起路由页面,然后传递参数到路由页,通过原生与flutter通信的方式传递路由名称(因为使用原有传递路由方式不可行,具体原因可以参考官方flutter页面预加载原理)。然后由路由页决定展示哪个flutter页面。如下:


image.png

这个方案的第一个问题就是如何传递路由以及参数,这里我使用的是MethodChannel通信方式。将路由名称以及参数统统包装到一个Map中,然后在FlutterContainerAcitivty.kt创建后立即执行方法告诉main.dart。所以这里的main.dart需要是StatefulWidget,这样可以在预加载之后再次更新。这样就达到了我们上面所说的目的。在main.dart中,我们可以拿到路由名称以及带过来的参数。然后再跟进路由名称去创建不同页面的widget,并通过构造传递参数。至此通过缓存的FlutterEngine传递路由名称和参数的问题解决。

问题:原生多次通过上述方案进入同一个flutter页面后,参数没有更新。经测试发现,第二次启动flutter页面后StatefulWidget的createState()方法没有执行导致UI没有刷新。

解决方案:当多次创建同一个StatefulWidget,只有第一次会执行createState()方法。但是我们会发现,之后会执行State中的didUpdateWidget(SubscribeMoneyDetail oldWidget)。通过该方法我们可以拿到当前StatefulWidget对象的属性,然后调用自己的setState(() {参数赋值});达到刷新UI的目的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容