相信很多APP开发人员都对flutter框架有了一定的了解和研究,谷歌推出的这个跨平台框架,确实有着自身的优势,接近原生的渲染性能,方便的flutter与native之间的通信机制。
但是在研究过flutter之后,很多人会有一种疑问,原有的native APP项目要如何处理,全部转成flutter平台吗?在评估这个问题的时候,我们要对自己的原有项目有着一个整体的认识,如果原有项目本身并不复杂,没有什么功能需要依赖native平台来实现(比如蓝牙、传感器等等),可以进行全新flutter平台的重构开发。反之,则我们需要谨慎考虑接入flutter平台,可以通过混合开发模式来实现。
所谓混合开发模式,就是一部分native代码,一部分flutter代码,共同构成项目主体。一般native代码为主模块,flutter代码作为一个依赖模块,类似于webview调用H5页面的模式来实现两个模块之间的界面跳转和通信
1、使用studio创建一个flutter module
2、Android工程导入刚刚创建的flutter module
3、修改Android工程的相关配置文件
settings.gradle
//加入下面配置 setBinding(new Binding([gradle: this])) evaluate(new File( settingsDir.parentFile, 'flutter_module/flutter_module/.android/include_flutter.groovy' ))
build.gradle
implementation project(':flutter')
4、实现Android界面跳转flutter界面
AndroidManifest.xml
跳转flutter指定界面
startActivity( FlutterActivity .withNewEngine().initialRoute("test")//指定路由 .build(MainActivity.this) );
flutter模块路由配置
Widget _widgetForRoute(String route) { print(route); switch (route) { case 'test': return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: Text('Flutter页面'), ), body: Center( child: Text('Flutter页面,route=$route'), ), ), ); case 'settings': return MaterialApp( debugShowCheckedModeBanner: false, home: SettingsPage("1"), ); default: return Center( child: Text('Unknown route: $route', textDirection: TextDirection.ltr), ); } } void main() => runApp(_widgetForRoute(window.defaultRouteName));//原生混合开发模式路由配置
1、了解flutter boost
flutter boost是闲鱼技术团队研究出的混合开发框架,目前比较主流的混合开发模式,官方介绍如下:
FlutterBoost是一个Flutter插件,它可以轻松地为现有原生应用程序提供Flutter混合集成方案。FlutterBoost的理念是将Flutter像Webview那样来使用。在现有应用程序中同时管理Native页面和Flutter页面并非易事。 FlutterBoost帮你处理页面的映射和跳转,你只需关心页面的名字和参数即可。
跟老方案类似,新的方案还是采用共享引擎的模式实现。主要思路是由Native容器Container通过消息驱动Flutter页面容器Container,从而达到Native Container与Flutter Container的同步目的。我们希望做到Flutter渲染的内容是由Naitve容器去驱动的。
简单的理解,我们想做到把Flutter容器做成浏览器的感觉。填写一个页面地址,然后由容器去管理页面的绘制。在Native侧我们只需要关心如果初始化容器,然后设置容器对应的页面标志即可。
2、native工程依赖flutter boost
在上面工程的基础上进行修改,完成flutter boost的依赖
pubspec.yaml新增依赖
#闲鱼 flutter_boost flutter_boost: git: url: 'https://github.com/alibaba/flutter_boost.git' ref: 'v3.0-hotfixes'
settings.gradle新增:
include ':flutter_module' project(':flutter_module').projectDir = new File('flutter_module/flutter_module')
build.gradle新增:
compileOptions { //编译需要设置成JAVA8 sourceCompatibility 1.8 targetCompatibility 1.8 } implementation project(':flutter_boost')
gradle.properties新增AndroidX的依赖
android.useAndroidX=true android.enableJetifier=true
3、完成native工程改造
Application初始化操作:
FlutterBoost.instance().setup(this, new FlutterBoostDelegate() { @Override public void pushNativeRoute(String pageName, HashMap
arguments) { // Intent intent = new Intent(FlutterBoost.instance().currentActivity(), NativePageActivity.class); // FlutterBoost.instance().currentActivity().startActivity(intent); } @Override public void pushFlutterRoute(String pageName, String uniqueId, HashMap arguments) { Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class, FlutterBoost.ENGINE_ID) .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.opaque) .destroyEngineWithActivity(false) .url(pageName) .urlParams(arguments) .build(FlutterBoost.instance().currentActivity()); FlutterBoost.instance().currentActivity().startActivity(intent); } },engine->{ engine.getPlugins(); } );
AndroidManifest.xml 定义flutterBoostActivity
native跳转flutter界面
HashMap
params=new HashMap<>(); params.put("params","22"); FlutterBoost.instance().open("settings",params);
4、完成flutter module对flutter boost的依赖
flutter模块路由定义
void main() => runApp(MyApp());//flutter_boost混合开发模式路由配置 class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } RouteObserver
routeObserver = RouteObserver (); class _MyAppState extends State { static Map routerMap = { '/': (settings, uniqueId) { return PageRouteBuilder ( settings: settings, pageBuilder: (_, __, ___) => MaterialApp( debugShowCheckedModeBanner: false, home: CountPage().buildPage(null), )); }, 'test': (settings, uniqueId) { return PageRouteBuilder ( settings: settings, pageBuilder: (_, __, ___) => MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: Text('Flutter页面'), ), body: Center( child: Text('Flutter页面,route=${settings.name}'), ), ), )); }, 'settings': (settings, uniqueId) { Map params=settings.arguments;//获取传递的参数 return PageRouteBuilder ( settings: settings, pageBuilder: (_, __, ___) => MaterialApp( debugShowCheckedModeBanner: false, home: SettingsPage(params['params']), )); }, }; Route routeFactory(RouteSettings settings, String uniqueId) { FlutterBoostRouteFactory func =routerMap[settings.name]; if (func == null) { return null; } return func(settings, uniqueId); } @override void initState() { super.initState(); } @override Widget build(BuildContext context) { print("init Fish_redux App"); //flutter boost return FlutterBoostApp( routeFactory, observers: [routeObserver], ); }
flutter模块内的界面之间跳转
BoostNavigator.of().push("test");//跳转路由