记得在flutter刚出来时,笔者就开始学习flutter。但因为当时嫌弃flutter复杂的层级组合且未推出稳定版,因此当时就放弃了深刻学习,现现在随着flutter的蓬勃发展及大佬们的力推,就又入坑flutter。java
虽然说flutter可以跨平台,但因为如今几乎都是现成的项目,因此不可能用flutter来重头开发,因此目前几乎都是采用native+flutter的混合开发方案。那么该方案该如何实现尼?android
首先,切换到native项目的根目录的上一级目录。以笔者项目为例,路径为D:\FlutterHybrid\FlutterHybridAndroid
,而后经过命令cd ../
切换到上一级目录。再执行下面命令来建立一个flutter模块。shell
flutter create -t module flutter_module
复制代码
上面的flutter_module
就是咱们建立的flutter模块名称。json
当flutter模块建立成功后,咱们就须要经过如下步骤来导入该模块。app
settings.gradle
文件中添加以下代码。setBinding(new Binding([gradle:this]))
evaluate(new File(
settingsDir.parentFile,'flutter_module/.android/include_flutter.groovy'
))
复制代码
添加完成后,就可以在Android Studio中看到flutter模块,以下图。
implementation project(':flutter')
来导入该模块。添加成功后就开始编译项目,这时候就可能会遇到以下错误。
minSdkVersion
不能小于Flutter模块的minSdkVersion
。解决方案就是把native项目的minSdkVersion
的值修改成大于flutter模块的minSdkVersion
的值。通过上面两步后,native项目就成功导入了flutter模块,这时候就能够来运行native项目。但在运行native项目时却又可能出现以下错误。less
app
目录下的
build.gradle
文件中添加以下代码。
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
复制代码
而后继续运行native项目,这时候就可以在设备上跑起来了,但如何验证flutter模块是否打包进apk里尼?这时候就能够借助Android Studio的apk分析工具。经过该工具能够发现apk包由如下内容组成。socket
flutter_assets
存放的就是flutter代码,到这里native项目就成功的导入了flutter模块。
注意:如在果项目中使用
AndroidX
,就会致使很严重的兼容性问题。因此若是项目中使用了AndroidX
,则要慎重导入flutter模块。若是必定要导入,则能够去阅读flutter官方提供的解决方案——AndroidX compatibility。ide
通过前面的一些操做,咱们就在Native项目中成功依赖了flutter模块,那么下面学习如何在Native项目中加载flutter页面。经过查看flutter模块代码能够发现,该模块提供了如下两种方式来加载flutter页面。工具
在flutter模块的Flutter
类中给咱们提供了一个方法——createView
。经过该方法,咱们能够将flutter页面构建成一个View。而View的相关操做想必对于Android开发者来讲都不陌生,因此就经过addView
将flutter页面添加到相应的地方。实现代码以下:post
public void onLoadFlutter(View view) {
View flutterView = Flutter.createView(this, getLifecycle(), "route1");
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(600, 600);
layoutParams.topMargin = 100;
addContentView(flutterView, layoutParams);
}
复制代码
一样,flutter模块也提供了方法——createFragment
,经过该方法就将flutter页面构建成一个fragment,而后根据fragment的操做将flutter页面添加到相应的地方。实现代码以下:
public void onLoadFlutter(View view) {
FragmentTransaction transaction= getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.someContainer,Flutter.createFragment("这里是flutter页面"));
transaction.commit();
}
复制代码
在前面讲述了如何在native项目中加载flutter页面,下面就来看一下flutter页面的代码。代码还使很简单的,基本的都是建立module时自动生成的代码。
import 'package:flutter/material.dart';
import 'dart:ui';
void main() => runApp(MyApp(
initParams: window.defaultRouteName,
));
class MyApp extends StatelessWidget {
final String initParams;
MyApp({Key key, @required this.initParams}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
title: 'Flutter Demo Home Page',
initParams: initParams,
),
);
}
}
class MyHomePage extends StatefulWidget {
final String initParams;
MyHomePage({Key key, this.title, this.initParams}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState(initParams);
}
class _MyHomePageState extends State<MyHomePage> {
final String initParams;
_MyHomePageState(this.initParams);
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'initParams:$initParams',
style: TextStyle(color: Colors.red),
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
复制代码
能够发现,在上面代码中,咱们传入了一个初始化属性,它其实就是一个路由名称,但其实咱们也传入一个json或者其余类型的数据,从而来作一些其余操做。其实这样就能够看作native与flutter之间的一种通讯。
flutter的优点之一就是在开发过程当中可以经过热重载功能来实现快速的调试,但经过运行上面代码就会发现,flutter模块代码修改后没法当即生效,须要从新打包Native才能生效。这样就让flutter的一个重大优点失效了,下降了调试效率。那么咱们能不能在混合项目中作到flutter模块的热重载尼?其实也是能够的,但须要通过一些步骤。
首先,关闭当前应用,注意:是要杀死当前应用所在进程,而不是退出应用。
其次,在flutter模块中输入命令flutter attach
,就会显示如下内容。
最后,再次打开应用,就会出现以下内容。
🔥 To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
它告诉咱们若是要热重载就按r键,想要热重启就按R键。当修改flutter代码后,按下r键,就会出现如下提示,表明修改为功。
通过上面的一些步骤,咱们就能够在混合项目中使用flutter的热重载功能,作到flutter修改后的当即生效。
其实混合项目的flutter模块调试与flutter项目的的惟一却别就是如何在Android Studio与设备之间创建socket链接。在flutter项目中,咱们能够直接点击debug
按钮来进行调试,但在混合项目中,该按钮就不起做用了,得经过其余方式来创建链接。Android Studio给咱们提供了flutter attach
按钮,经过该按钮,flutter模块就能跟设备创建链接,就能对flutter模块进行调试。
经过上面的一些讲解,相信就可以使用native+flutter的混合开发了。但细心一点就会发现,在前面的讲解中,flutter模块并无与native项目进行通讯,那么该如何通讯尼?在笔者的一篇看懂Android与Flutter之间的通讯中作了详细的介绍。