内容简介:记得在flutter刚出来时,笔者就开始学习flutter。但由于当时嫌弃flutter复杂的层级组合且未推出稳定版,所以当时就放弃了深入学习,现如今随着flutter的蓬勃发展及大佬们的力推,就又入坑flutter。虽说flutter能够跨平台,但由于现在几乎都是现成的项目,所以不可能用flutter来重头开发,所以目前几乎都是采用native+flutter的混合开发方案。那么该方案该如何实现尼?首先,切换到native项目的根目录的上一级目录。以笔者项目为例,路径为
记得在flutter刚出来时,笔者就开始学习flutter。但由于当时嫌弃flutter复杂的层级组合且未推出稳定版,所以当时就放弃了深入学习,现如今随着flutter的蓬勃发展及大佬们的力推,就又入坑flutter。
虽说flutter能够跨平台,但由于现在几乎都是现成的项目,所以不可能用flutter来重头开发,所以目前几乎都是采用native+flutter的混合开发方案。那么该方案该如何实现尼?
1、flutter模块的导入
首先,切换到native项目的根目录的上一级目录。以笔者项目为例,路径为 D:\FlutterHybrid\FlutterHybridAndroid ,然后通过命令 cd ../ 切换到上一级目录。再执行下面命令来创建一个flutter模块。
flutter create -t module flutter_module 复制代码
上面的 flutter_module 就是我们创建的flutter模块名称。
当flutter模块创建成功后,我们就需要通过以下步骤来导入该模块。
- 首先在在
settings.gradle文件中添加如下代码。setBinding(new Binding([gradle:this])) evaluate(new File( settingsDir.parentFile,'flutter_module/.android/include_flutter.groovy' )) 复制代码添加完成后,就能够在Android Studio中看到flutter模块,如下图。 - 其次,在能够正确显示flutter模块后,我们就需要通过
implementation project(':flutter')来导入该模块。添加成功后就开始编译项目,这时候就可能会遇到如下错误。 这就是我们需要注意的一点, native项目的minSdkVersion不能小于Flutter模块的minSdkVersion。解决方案就是把 native项目的minSdkVersion的值修改为大于flutter模块的minSdkVersion的值 。
经过上面两步后,native项目就成功导入了flutter模块,这时候就可以来运行native项目。但在运行native项目时却又可能出现如下错误。
app 目录下的
build.gradle
文件中添加如下代码。
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
复制代码
然后继续运行native项目,这时候就能够在设备上跑起来了,但如何验证flutter模块是否打包进apk里尼?这时候就可以借助Android Studio的apk分析工具。通过该 工具 可以发现apk包由以下内容组成。
flutter_assets
存放的就是flutter代码,到这里native项目就成功的导入了flutter模块。
2、native项目加载flutter页面
经过前面的一些操作,我们就在Native项目中成功依赖了flutter模块,那么下面学习如何在Native项目中加载flutter页面。通过查看flutter模块代码可以发现,该模块提供了以下两种方式来加载flutter页面。
- 将flutter页面构建成View,通过addView来显示flutter页面
- 将flutter页面构建成Fragment,通过对fragment的操作来显示flutter页面
2.1、将flutter页面构建成View
在flutter模块的 Flutter 类中给我们提供了一个方法—— createView 。通过该方法,我们可以将flutter页面构建成一个View。而View的相关操作想必对于Android开发者来说都不陌生,所以就通过 addView 将flutter页面添加到相应的地方。实现代码如下:
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);
}
复制代码
2.2、将flutter页面构建成flutter
同样,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();
}
复制代码
2.3、flutter页面
在前面讲述了如何在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之间的一种通信。
3、flutter模块的调试
3.1、flutter模块的热重载
flutter的优势之一就是在开发过程中能够通过热重载功能来实现快速的调试,但通过运行上面代码就会发现,flutter模块代码修改后无法立即生效,需要重新打包Native才能生效。这样就让flutter的一个重大优势失效了,降低了调试效率。那么我们能不能在混合项目中做到flutter模块的热重载尼?其实也是可以的,但需要经过一些步骤。
-
首先,关闭当前应用,注意: 是要杀死当前应用所在进程,而不是退出应用 。
-
其次,在flutter模块中输入命令
flutter attach,就会显示以下内容。 -
最后,再次打开应用,就会出现如下内容。
请注意图中的这段话
:fire: To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
它告诉我们如果要热重载就按 r 键,想要热重启就按 R 键。当修改flutter代码后,按下 r 键,就会出现以下提示,代表修改成功。
经过上面的一些步骤,我们就可以在混合项目中使用flutter的热重载功能,做到flutter修改后的立即生效。
3.2、flutter模块的调试
其实混合项目的flutter模块调试与flutter项目的的唯一却别就是如何在Android Studio与设备之间建立socket连接。在flutter项目中,我们可以直接点击 debug 按钮来进行调试,但在混合项目中,该按钮就不起作用了,得通过其他方式来建立连接。Android Studio给我们提供了 flutter attach 按钮,通过该按钮,flutter模块就能跟设备建立连接,就能对flutter模块进行调试。
4、总结
通过上面的一些讲解,相信就能够使用native+flutter的混合开发了。但细心一点就会发现,在前面的讲解中,flutter模块并没有与native项目进行通信,那么该如何通信尼?在笔者的下一篇文章会进行详细讲解。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C和C++代码精粹
阿林森 / 董慧颖 / 人民邮电出版社 / 2003-4-1 / 59.00
《C和C++代码精粹》基于作者备受好评的C/C++ User Journal杂志上的每月专栏,通过大量完全符合ISO标准C++的程序集合,说明了C++真正强大的威力,是C和C++职业程序员的实践指南。可以帮助有一定经验的C和C++程序员深入学习这两种密切相关的语言,对书中代码的参悟和应用,可以帮助他们从根本上提高使用程序的效率。一起来看看 《C和C++代码精粹》 这本书的介绍吧!