Android原生项目集成Flutter Module

Flutter安装

git clone下来,然后配置一下path即可

集成步骤

(一)在目标目录的同级目录执行如下命令,创建

$ flutter create -t module <module_name>

(二)进入到你创建的flutter目录下,执行:

$ cd .android
$ ./gradlew flutter:assembleDebug

可能出现的错误: 这时候可能卡在resoving dependencies gradle-3.1.4.pom等网络超时错误,这个和AS执行gradle一样需要配置代理。undefined在.android目录下gradle.properties文件配置合适的代理,就可以解决这个问题。 然后可能出现Could not find lint-gradle-api.jar这样的神奇问题,这个的处理方法是:进入到flutter安装的目录下(假定是.flutter),然后修改目录下的.flutter/packages/flutter_tools/gradle/build.gradle文件,将 repositories { jcenter() maven { url 'https://dl.google.com/dl/android/maven2' } } 修改为:repositories { maven { url 'https://dl.google.com/dl/android/maven2' } jcenter() } (其实就是两个位置调换一下,如果某些资源还是找不到,再在前面加一个google()

成功执行后,会在.android/Flutter/build/outputs/aar/目录下,创建一个flutter-debug.aar的包文件

(三)在项目的setting.gradle加上如下代码:

setBinding(new Binding([gradle: this]))                               
evaluate(new File(                                                 
        settingsDir.parentFile,                                     
        '<module_name>/.android/include_flutter.groovy'               
))

这里是将Flutter项目导入到AS项目中,不过导入的flutter模块只有java代码,想写dart还是要另外开一个IDE。

(四)然后需要在build.gradle(app)中加入如下依赖:

implementation project(':flutter')

此时sync就一般可以成功了,如果失败了,按照提示逐步解决即可。

笔者这里遇到两个问题,都比较好解决:gradle插件版本问题,flutter模块辛苦3.x以上,需要将主工程的gradle版本升级上去 flutter模块和主工程引用的第三方库版本冲突,常规解决即可,将版本设为一致,或将flutter中的implementation改为api即可

项目中使用Flutter

前面完成了的话,app已经可以run起来了。现在看怎么引入Flutter的代码。

了解了Flutter的知识,其实可以感觉得到,,Flutter中的widget等控件or布局,对于android或iOS来说是透明的,平台只会认为整个Flutter展示的内容是一个view。

所以在android中的用Flutter,就是用一个view去承载Flutter项目。

其实可以理解为flutter就是一个提供了各种绘制方法的view,在Flutter里面的操作就是对view的onDraw方法的控制(还有touch事件)

所以直接当做view去使用的话,就是这样:

View flutterView = Flutter.createView(
  MainActivity.this,
  getLifecycle(),
  "route1"
);
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600,800);
layout.leftMargin = 100;
layout.topMargin = 200;
activity.addContentView(flutterView, layout);

对应的Flutter的lib中main.dart文件内容是这样:

import 'dart:ui';
import 'package:flutter/material.dart';

void main() => runApp(_widgetForRoute(window.defaultRouteName));

Widget _widgetForRoute(String route) {
  switch (route) {
    case 'route1':
      return SomeWidget(...);
    case 'route2':
      return SomeOtherWidget(...);
    default:
      return Center(
        child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
      );
  }
}

window.defaultRouteName会接受到主项目中传入的路由路径,然后返回对应的widget的,之后这个view就完全可以当做一整个Flutter app去对待了。但它的生命周期是由Activity管理的,所以Flutter也可以用Fragment去承载:

FragmentTransaction tx = fragmentActivity.getSupportFragmentManager().beginTransaction();
tx.replace(R.id.someContainer, Flutter.createFragment("route1"));
tx.commit();

看源码的话,FlutterFragment这里就是将FlutterView wrap了一下,在onCreateView里直接返回了FlutterView。

之后对于FlutterView就是完全是在Flutter项目中开发了。

补充

集成到项目工程中时遇到两个问题。

  • 一个是Flutter不支持armeabi,而我们项目中库都是armeabi的,只能通过将armeab-v7a强行打入armeabi来处理,这样带来的问题是某些不支持armeabi-v7a的cpu设备会无法运行。(目前没有很好的解决方法,不过现在主流的设备都已经支持armeabi-v7a,倒是问题不大。具体数据有待调查)
  • 另一个就是编译时出现错误:没有初始化虚拟机,尝试了各种方法,后来发现前面的编译指令应该去掉flutter:,否则不会打包flutter_assets,这个有点坑~用下面指令就没有问题。
$ ./gradlew assembleDebug

Wrote by Kevin(a2V2aW56aGFuMDQxN0BvdXRsb29rLmNvbQ==)

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mukekeheart的iOS之旅

Android基础总结(4)——广播接收器

  在Android中的每个应用程序可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能来自于系统的,也可能来自于其他应用程序...

278100
来自专栏.Net移动开发

关于发布IOS的方法(本人亲身经历折腾很久终于成功)

前情提要:这位.NET程序员兄弟使用Smobiler开发了一个APP,尽管Smobiler云平台已经最大限度的简化了iOS应用的打包操作,但仍绕不开苹果公司强制...

16910
来自专栏点滴积累

OpenStack(企业私有云)万里长征第五步——虚拟机Migrate&Resize

一、前言 上一篇文章讲了OpenStack的部署和简单操作,今天介绍一下如何实现虚拟机的Migrate以及Resize。Migrate操作和Resize操作基本...

41950
来自专栏菩提树下的杨过

phabricator在mac上的搭建

前提:phabricator主要是由php写的,而且是以website方式运行的,所以mac上要先安装好 php + nginx(或apache) + mysq...

13420
来自专栏Golang语言社区

51. Socket服务端和客户端使用TCP协议通讯 | 厚土Go学习笔记

Socket服务器是网络服务中常用的服务器。使用 go 语言实现这个业务场景是很容易的。 这样的网络通讯,需要一个服务端和至少一个客户端。 我们计划构建一个这样...

34160
来自专栏贾鹏辉的技术专栏@CrazyCodeBoy

React Native发布APP之签名打包APK

React Native发布APP之签名打包APK ---- 用React Native开发好APP之后,如何将APP发布以供用户使用呢?一款APP的发布流程...

29050
来自专栏腾讯Bugly的专栏

H5 缓存机制浅析 移动端 Web 加载性能优化

1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性。离线存储(也可称为缓存机制)是其中一个非常重要的特性。H5 引入的离...

39620
来自专栏散尽浮华

linux下sendmail邮件系统安装操作记录

电子邮件系统的组成: 1)邮件用户代理(Mail User Agent , MUA),MUA是一个邮件系统的客户端程序,它提供了阅读,发送和接受电子邮件的用户接...

52390
来自专栏向治洪

认识Kubernates(K8S)

在后端开发中,在介绍Jenkins的可伸缩部署方式上,主要有两种方式:一种是基于Docker(或者docker-swarm 集群)的部署方式,另外一种是基于ku...

85080
来自专栏开心的学习之路

04 Nifty自定义带图片的下拉框

读了好久源代码,才搞明白怎么回事,其实现在回过头来想想很简单,主要是寻找的过程艰难。 自定义一个control 在resources里面新建一个文件夹MyCon...

29580

扫码关注云+社区

领取腾讯云代金券