Flutter- Android项目集成flutter模块
Android项目集成flutter模块
- 创建Flutter module
- 添加Flutter module依赖
- Native跳转Flutter页面 -Activity
- flutter路由配置
- Android中跳转指定路由
- 单例FlutterEngine缓存管理
- 在Application中初始化
- 使用
- Flutter跳转到Native
- Native创建抽象Bridge
- Flutter创建Bridge
- 使用
- Native端发送消息到Flutter端
- 构建flutter aar
创建Flutter module
在做混合开发之前我们首先需要创建一个Flutter module
假如Native项目是:xxx/flutter_hybrid/native项目
$ cd xxx/flutter_hybrid//create flutter module
$ flutter create -t module flutter_module//指定报名
$ flutter create -t module --org cn.xxstudy flutter_module
也可以使用Androidstudio创建
添加Flutter module依赖
settings.gradle
添加如下代码
include ':app'
...
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir.parentFile,'flutter_module/.android/include_flutter.groovy'
))//可选,主要作用是可以在当前projec中显示flutter_module方便查看和编写代码
include ':flutter_module'
project(':flutter_module').projectDir = new File('../flutter_module')
setBinding
与evaluate
允许Flutter模块包括它自己在内的任何flutter插件,在settings.gradle
中以类似::flutter
、package_info
、:vidoe_palyer
的方式存在
添加依赖:app/build.gradle
...
dependencies{...implementation project(':flutter')...
}
必须添加Java8的编译选项
compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8
}
Native跳转Flutter页面 -Activity
- 最简单的方式(不推荐)
在AndroidManifest.xml
中注册
<activityandroid:name="io.flutter.embedding.android.FlutterActivity"android:theme="@style/MyTheme"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:hardwareAccelerated="true"android:windowSoftInputMode="adjustResize"/>
startActivity
:startActivity(new Intent(context, FlutterActivity.class
这个时候target flutter page 就是Flutter module中的默认页面,如果flutter 中有多个页面,需要跳转时指定路由名称,flutter 中也需要进行路由配置
flutter路由配置
class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),initialRoute: '/',routes: {'login': (context) => const ConnectLogin(),'/': (context) => const RefreshListViewDemo()},);}
}
Android中跳转指定路由
Intent intent = FlutterActivity.withNewEngine().initialRoute("login").build(this);startActivity(intent);
- 推荐方式
由于上述的方式每次都需要创建一个FlutterEngine
,创建FlutterEngine
代价是比较大的,一些低端手机在跳转时会出现短暂的黑屏问题,因此可以先提前缓存好FlutterEngine
单例FlutterEngine缓存管理
public class FlutterCacheManager {public static final String LIST = "list";public static final String LOGIN = "login";private FlutterCacheManager() {}public static FlutterCacheManager getInstance() {return FlutterCacheManagerHolder.INSTANCE;}private static class FlutterCacheManagerHolder {private static final FlutterCacheManager INSTANCE = new FlutterCacheManager();}public void preLoad(Context context) {Looper.myQueue().addIdleHandler(() -> {initFlutterEngine(context, LIST);initFlutterEngine(context, LOGIN);return false;});}@NonNullpublic FlutterEngine getCacheFlutterEngine(Context context, String moduleName) {FlutterEngine flutterEngine = FlutterEngineCache.getInstance().get(moduleName);if (flutterEngine == null) {flutterEngine = initFlutterEngine(context, moduleName);}return flutterEngine;}private FlutterEngine initFlutterEngine(Context context, String moduleName) {FlutterEngine flutterEngine = new FlutterEngine(context);//set route nameflutterEngine.getNavigationChannel().setInitialRoute(moduleName);//init bridgeFlutterBridge.getInstance().init(flutterEngine);flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());FlutterEngineCache.getInstance().put(moduleName, flutterEngine);}
}
在Application中初始化
@Override
public void onCreate() {context = this;super.onCreate();FlutterCacheManager.getInstance().preLoad(this);...}
使用
FlutterCacheManager.getInstance().getCacheFlutterEngine(this, FlutterCacheManager.LOGIN);
Intent intent=FlutterActivity.withCachedEngine(FlutterCacheManager.LOGIN).build(this);
Flutter跳转到Native
Native创建抽象Bridge
public interface IBridge<P, Callback> {void sendMessage(String method, Object arguments);void sendMessage(String method, Object arguments, MethodChannel.Result callback);void onBack(P p);void goToNative(P p);
}
public class FlutterBridge implements IBridge<Object, MethodChannel.Result>, MethodChannel.MethodCallHandler {private List<MethodChannel> methodChannels = new ArrayList<>();private FlutterBridge() {}public static FlutterBridge getInstance() {return FlutterBridgeHolder.INSTANCE;}private static class FlutterBridgeHolder {private static final FlutterBridge INSTANCE = new FlutterBridge();}//需要在FlutterCacheManager 创建FlutterEngine时初始化public void init(FlutterEngine engine) {//name need to be the same as flutterMethodChannel methodChannel = new MethodChannel(engine.getDartExecutor(), "FlutterBridge");//set handlermethodChannel.setMethodCallHandler(this);methodChannels.add(methodChannel);}@Overridepublic void sendMessage(String method, Object arguments) {for (MethodChannel methodChannel : methodChannels) {methodChannel.invokeMethod(method, arguments);}}@Overridepublic void sendMessage(String method, Object arguments, MethodChannel.Result callback) {for (MethodChannel methodChannel : methodChannels) {methodChannel.invokeMethod(method, arguments, callback);}}@Overridepublic void onBack(Object o) {Activity currentActivity = ActivityManager.getInstance().getCurrentActivity();if (currentActivity != null && !currentActivity.isDestroyed()) {currentActivity.onBackPressed();}}@Overridepublic void goToNative(Object o) {//start HomeActivityActivity currentActivity = ActivityManager.getInstance().getCurrentActivity();currentActivity.startActivity(new Intent(currentActivity, HomeActivity.class));currentActivity.finish();}@Overridepublic void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {switch (call.method) {case "onBack":onBack(call.arguments);break;case "goToNative":goToNative(call.arguments);break;default:break;}}
}
Flutter创建Bridge
class FlutterBridge {static final FlutterBridge _instance = FlutterBridge._();final MethodChannel _bridge = const MethodChannel('FlutterBridge');final _listener = {};FlutterBridge._() {_bridge.setMethodCallHandler((call) {String method = call.method;if (_listener[method] != null) {return _listener[method](call);}return Future.value();});}static FlutterBridge getInstance() {return _instance;}register(String method, Function(MethodCall) callback) {_listener[method] = callback;}unRegister(String method) {_listener.remove(method);}MethodChannel get bridge => _bridge;goToNative([Map? params]) {_bridge.invokeMethod("goToNative", params);}onBack() {_bridge.invokeMethod('onBack');}
}
使用
child: ElevatedButton(onPressed: () {FlutterBridge.getInstance().goToNative();},style: ButtonStyle(elevation: MaterialStateProperty.all(0),backgroundColor:MaterialStateProperty.all<Color>(Colors.transparent)child: Text("LOGIN",style: TextStyle(fontFamily: 'QuicksandMedium', fontSize: 19.sp)))),
Native端发送消息到Flutter端
sendMessage.setOnClickListener((view) -> {FlutterBridge.getInstance().sendMessage("listener", "by Native message", new MethodChannel.Result() {@Overridepublic void success(@Nullable Object result) {LogUtils.Sensi("LoginHomeActivity.java","success(LoginHomeActivity.java:156)" + result);}@Overridepublic void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {LogUtils.Sensi("LoginHomeActivity.java","error(LoginHomeActivity.java:163)errorCode=" + errorCode + ",errorMessage=" + errorMessage);}@Overridepublic void notImplemented() {}});
});
@overridevoid initState() {FlutterBridge.getInstance().register('listener', (MethodCall call) {print('receive Native message arguments=${call.arguments} method=${call.method}');return Future.value('by flutter message ${DateTime.now().toIso8601String()}');});super.initState();}@override
void dispose() {FlutterBridge.getInstance().unRegister('listener');super.dispose();
}
构建flutter aar
$ cd .android/
$ ./gradlew flutter:assembleRelease
将在.android/Flutter/build/outputs/aar/
中生成一个flutter-release.aar
归档文件
Flutter- Android项目集成flutter模块相关推荐
- 原生App项目集成flutter混合开发详细指南
记得去年9月份的时候谷歌在上海有一次开发者大会,去参加的时候关注到了flutter,随后没过多久就发布了1.0版本.18年底的时候用flutter做了个小项目,发现flutter确实挺好用的.于是尝试 ...
- Flutter:Android/iOS集成Flutter模块
一.Android工程集成Flutter模块工程: 1.使用命令创建Flutter模块工程lib_flutter(与Android工程属于同级目录): flutter create -t module ...
- Android项目集成穿山甲开屏/插屏/横幅广告教程大全
Android项目集成穿山甲开屏/插屏/横幅广告教程大全 开发及项目环境说明 Android Studio 2020.3.1 Patch 4/203.7717.56.2031.7935034 jdk1 ...
- iOS 项目集成Flutter
#最近移动端火爆无非是Flutter--舍我其谁,而官网的引导之中鲜有说怎么在已有项目中去集成Flutter,今天我们就再蹭个热门来进行一个iOS集成 1 创建iOS项目(做测试使用) 2 cocoa ...
- Android studio集成flutter
1.获取Flutter SDK 视窗安装|扑动 (flutter.dev) 2.配置环境变量 3.Android Studio安装Flutter插件 4.打开管理窗口cmd,输入flutter doc ...
- 穿山甲android对接错误码40029,空Android项目集成Cocos、穿山甲。Lua调用网络接口。...
1. 搭建安卓空项目.集成cocos.穿山甲广告新建安卓项目start new android projectEmpty Activity包名这里要和穿山甲上面已创建的应用的包... 1. 搭建安卓空 ...
- Android 项目集成 Freeline
1.什么是FreeLine? (官网描述) Freeline是由蚂蚁聚宝Android团队开发的一款针对Android平台的增量编译工具.它可以充分利用缓存文件,在几秒钟内迅速地对代码的改动进行编译并 ...
- Android公共jar,使用JitPack管理Android项目中公共模块库
随着项目的功能越来越多,代码和模块维护也越来越复杂,为了减少主项目的代码量,一般都会将一些公共使用的类或者功能模块抽离出来,与主项目解耦分离,当主项目中需要使用的时候,直接进行引用即可. 现在Andr ...
- Android 项目集成有米 SDK 添加广告
集成 SDK 的基本配置 步骤一 步骤二 步骤三 步骤四 集成 SDK 的无积分广告 步骤五 步骤六 步骤七 步骤八 步骤九 我们有时候需要在app里面,添加一些广告,作为额外的一些收入,那么该怎么办 ...
- bugly android 错误不上报,Flutter Android 端集成 Bugly 的异常上报和升级功能
前提 Flutter 版本:1.17.0地址,别用最新版本或者比较老的版本.我之前使用1.13.0版本也会出现问题. Dart版本:2.8.1使用Flutter中提供的版本 ok ,在大版本相同的情况 ...
最新文章
- 互联网公装企业“inDeco领筑智造”完成A+B轮近1.1亿元融资
- php mysql 超时时间_php mysql超时设置方法
- 个推用户画像的实践与应用
- LINUX 触摸屏驱动
- 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为参数,泛型函数
- mysql 查看锁_SQL-mysql锁等待与死锁
- 牛顿法的优缺点及特征
- Lingo 软件的使用 数学建模 司守奎
- A4双面打印多少钱一张
- 自由手写体字帖pdf_何某手写体:一款随心所欲充满趣味的日系手写字体 免费商用...
- js pug 代码_pug模板引擎(原jade)
- PHP、Python 和 Ruby 语言的区别
- web前端入门到实战:行内和块状元素水平居中与单行或多行文本垂直居中及隐性改变display类型
- Macbook安装pkg
- Ubuntu20.04 搭建repo + gitlab的代码管理系统
- IPV6在容器云中的部署(一)
- android 状态栏显示 耳机图标显示,Android4.0-4.4 加入支持状态栏显示耳机图标方法(支持带不带MIC的两种耳机自己主动识别)...
- 35岁的程序员:第16章,双重担忧
- Unity网格系统(1)网格生成
- F函数的极大极大算法
热门文章
- 测试打印机性能的软件,打印性能测试(一)
- 嘉善 机器人比赛_第十一届省青少年机器人大赛嘉善摆擂
- 登入ftp:500 OOPS: vsf_sysutil_bind, maximum number of attempts to find a listening port exceeded
- 步进电机驱动器怎么设置细分
- 计算机联锁架的构成,TYJL-II计算机联锁的特点
- Android破解学习之路(十五)—— 【Unity3D】洛菲斯的呼唤(Lophis roguelike)无限金币(道具)的实现 破解
- java开源项目-SpringBoot在线教育平台
- STM8L152K4T6原理图与开发程序
- TTU智能配电终端_【TMT投资】智能配电网简析(上)
- 微信小程序(云开发)----微信支付