在实际开发过程中,往往我们会是基于原有项目结合flutter开发的混合开发模式。因此,我们有必要来看看闲鱼开发一个混合通信方案-flutterboost。就目前使用的情况来看,这套方案对开发者比较友好,闲鱼官方一直在维护,值得推荐。来一波地址:Flutterboost
集成步骤其实官网都有,我这里就简单列一下,方便大家参考,具体可以参照官方文档。
一、首先你得有一个flutter的module项目,记住是module模式的项目,下面是 mac 电脑Android Studio Arctic Fox | 2020.3.1 Patch 4 版本的新建flutter module过程。
1.file--new flutter project
2. 选择flutter的sdk目录,这个提前下好,不明白的,百度一下flutter安装教程哈。
3.这里主要记得填项目名和选择project type为module,其他自己看着选就行了 。继续点finish,就完成了。
二、有了flutter_module项目,既然是混合开发,原生Android项目和原生ios项目是少不了,按正常方式新建就好了。这里注意下,不是说一定要flutter,ios,android三个项目齐全才能开发运行的意思哈,不需要ios平台的包自然就不需要新建ios项目了。最终的目录结构参考如下,当然,也可以原生项目文件里嵌套flutter_module项目,只是后面配置引用关联的时候,要调整一下配置,但是嵌套没必要,不建议。
好了,至此,三个项目都有了,下面看下,Android项目是如何关联flutter module的,原理其实很简单,就是把flutter项目当成安卓的一个module关联起来而已,这种方式Android里面经常用到, ios应该也差不多,ios的同学可以参考官网配置。
1.用Android studio打开flutter_module项目,找到pubspec.yaml文件,在dependencies:下添加flutterboost的依赖。然后点击右上角的pub get加载依赖。
flutter_boost: git: url: 'https://github.com/alibaba/flutter_boost.git' ref: 'v3.0-null-safety-preview.18'
2.运行flutter_module项目,正常情况是可以运行起来,并且显示默认的flutter界面效果。检查项目中是否存在.android和.ios目录。
3.没问题后,打开Android项目,找到settings.gradle文件,新增下面代码。主要根据自己的实际情况修改路径。
/**
* 这里注意evaluate 里面file路径参数的第二个参数,是flutter项目里.android目录的groovy的具体路径,
* 其中flutter_module 是flutter的项目名,不是固定的,根据自己实际的flutter项目名修改。
*
*/
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'/flutter_module/.android/include_flutter.groovy'
))
include ':flutter_module'
project(':flutter_module').projectDir = new File('/flutter_module')
4.找到app的gradle文件,新增依赖
implementation project(':flutter')
implementation project(':flutter_boost')
5.在清单文件添加注册信息。
<activity
android:name="com.idlefish.flutterboost.containers.FlutterBoostActivity"
android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" >
</activity>
<meta-data android:name="flutterEmbedding"
android:value="2">
</meta-data>
6.同步sync Android 项目,并运行,正常情况这个时候能正常运行起来项目。如有报错,可以留言或者查看flutterboost官网集成文档。
集成完毕后,接下来看看如何实现初始化和基本使用。
7.在Android 项目的application里面初始化。
private fun initFlutter(context: Application ){
val delegate= MyFlutterBoostDelegate()
FlutterBoost.instance().setup(context, delegate,
FlutterBoost.Callback { engine: FlutterEngine -> engine.plugins
}
)
}
MyFlutterBoostDelegate 类很简单 ,class MyFlutterBoostDelegate:FlutterBoostDelegate {
},重写下面2个方法就ok了。这2个方法多提一嘴,当你使用flutterboost的跳转api在原生和flutter直接跳转的时候,这2个方法才会回调。
FlutterBoost.instance().setup(this, new FlutterBoostDelegate() {
@Override
public void pushNativeRoute(FlutterBoostRouteOptions options) {
//这里看方法名,很明显是打开原生页面的回调,
//根据options.pageName来判断 跳转哪个页面.跳转逻辑和原生跳转代码一样。
/**
*FlutterBoost.instance().currentActivity()
*.startActivityForResult(intent, options.requestCode())
**/
}
@Override
public void pushFlutterRoute(FlutterBoostRouteOptions options) {
Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class)
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.destroyEngineWithActivity(false)
.uniqueId(options.uniqueId())
.url(options.pageName())
.urlParams(options.arguments())
.build(FlutterBoost.instance().currentActivity());
FlutterBoost.instance().currentActivity().startActivity(intent);
}
}, engine -> {
});
8. 打开flutter_module项目找到main.dart文件, 修改内容如
(这个是flutterboost官网代码可自行参考。);
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
void main() {
///这里的CustomFlutterBinding调用务必不可缺少,用于控制Boost状态的resume和pause
CustomFlutterBinding();
runApp(MyApp());
}
///创建一个自定义的Binding,继承和with的关系如下,里面什么都不用写
class CustomFlutterBinding extends WidgetsFlutterBinding with BoostFlutterBinding {}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
/// 由于很多同学说没有跳转动画,这里是因为之前exmaple里面用的是 [PageRouteBuilder],
/// 其实这里是可以自定义的,和Boost没太多关系,比如我想用类似iOS平台的动画,
/// 那么只需要像下面这样写成 [CupertinoPageRoute] 即可
/// (这里全写成[MaterialPageRoute]也行,这里只不过用[CupertinoPageRoute]举例子)
///
/// 注意,如果需要push的时候,两个页面都需要动的话,
/// (就是像iOS native那样,在push的时候,前面一个页面也会向左推一段距离)
/// 那么前后两个页面都必须是遵循CupertinoRouteTransitionMixin的路由
/// 简单来说,就两个页面都是CupertinoPageRoute就好
/// 如果用MaterialPageRoute的话同理
Map<String, FlutterBoostRouteFactory> routerMap = {
'mainPage': (RouteSettings settings, String uniqueId) {
return CupertinoPageRoute(
settings: settings,
builder: (_) {
Map<String, Object> map = settings.arguments as Map<String, Object> ;
String data = map['data'] as String;
return MainPage(
data: data,
);
});
},
'simplePage': (settings, uniqueId) {
return CupertinoPageRoute(
settings: settings,
builder: (_) {
Map<String, Object> map = settings.arguments as Map<String, Object>;
String data = map['data'] as String;
return SimplePage(
data: data,
);
});
},
};
Route<dynamic> routeFactory(RouteSettings settings, String uniqueId) {
FlutterBoostRouteFactory func = routerMap[settings.name] as FlutterBoostRouteFactory;
return func(settings, uniqueId);
}
Widget appBuilder(Widget home) {
return MaterialApp(
home: home,
debugShowCheckedModeBanner: true,
///必须加上builder参数,否则showDialog等会出问题
builder: (_, __) {
return home;
},
);
}
@override
Widget build(BuildContext context) {
return FlutterBoostApp(
routeFactory,
appBuilder: appBuilder,
);
}
}
class MainPage extends StatelessWidget {
const MainPage({Object data});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(child: Text('Main Page')),
);
}
}
class SimplePage extends StatelessWidget {
const SimplePage({Object data});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(child: Text('SimplePage')),
);
}
}
9.跳转方法,可以单独写个类,
class FBRouteManager {
///跳转
static Future push(String routeName, [Map<String, dynamic>? parameter]) {
return BoostNavigator.instance
.push(routeName, withContainer: false, arguments: parameter);
}
}
到这里基本已经集成完毕了。由于版幅有限,如有问题,欢迎留言。