Flutter以离线aar嵌入安卓工程的具体做法
血泪史
项目引入了FlutterBoost以嵌入flutter模块,但是开发的人员分散,组织结构复杂,技术水平参差不齐,导致flutter环境安装推行困难(尽管我提供了环境安装的文档),所以保险起见,用离线的形式将 flutter模块嵌入到安卓原生工程。
研究期间,经历了屎山项目的各种环境问题(主要是Android Gradle Plugin 版本,Jdk版本,flutterSDk版本,以及FlutterBoost版本各种不兼容,各种看不懂的编译器问题),最终以 aar so 离线文件的方式,让原生工程能够以Fragment的形式,或者以activity的方式打开 flutter页面,解除了 Flutter环境与原生工程的硬性绑定关系,实现了flutter模块的静态发布,又能够支撑flutter开发者的动态调试,不影响flutter模块的开发工作。
综合经验总结如下,供有类似经历的开发者参考。
最终方案
先声明每个关键部分的版本号:
- JDK - 11
- Gradle Wrapper - 6.7
- FlutterBoost - 3.1.3
- Flutter sdk - 2.5.3
- AndroidStudio - Electric Eel | 2022.1.1 Patch 2
Flutter侧
步骤1,创建Flutter Module工程
创建Flutter工程时,必须选择module类型,因为它才是能够嵌入native的工程形式。
创建完成之后尝试去打它的aar包,
坑1
第一个坑来了,有可能你们不会出现,这个属于环境问题:
* Where:
Settings file 'D:\testPro\20230801\flutter_pro_002.android\settings.gradle' line: 6
* What went wrong:
A problem occurred evaluating settings 'android_generated'.
> BUG! exception in phase 'semantic analysis' in source unit 'D:\testPro\20230801\flutter_pro_002.android\include_flutter.groovy' Unsupported class file major version 62
提取问题关键字 :Unsupported class file major version 62
, 它发生的主要原因是:
你尝试运行一个使用了较高版本的 Java 编译器编译的类文件,而当前运行环境的 Java 版本不支持该版本的类文件
, 简单来说就是 JRE和 JDK不匹配,比如jdk用的是 17,但是jre停留在 11。
解决方法,只要让 两者一致即可,具体做法为,找到 flutter项目的 gradle.properties
文件,加入此属性:
org.gradle.java.home=D://env//androidStudio//jbr
(注意,找到你当前安卓项目设置的JDK路径,D://env//androidStudio//jbr
是我自己本机的JDK路径,不要照搬)
然后再次尝试 打aar,就会发现:
D:\env\flutter_windows_2.5.3-stable\flutter\bin\flutter.bat --no-color build aar
Building with sound null safety
Running Gradle task 'assembleAarDebug'... 41.0s
√ Built build\host\outputs\repo.
Running Gradle task 'assembleAarProfile'... 37.7s
√ Built build\host\outputs\repo.
Running Gradle task 'assembleAarRelease'... 42.0s
√ Built build\host\outputs\repo.
Consuming the Module
1. Open <host>\app\build.gradle
2. Ensure you have the repositories configured, otherwise add them:
String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.谷歌apis.com"
repositories {
maven {
url 'D:\testPro\20230801\flutter_pro_002\build\host\outputs\repo'
}
maven {
url "$storageUrl/download.flutter.io"
}
}
3. Make the host app depend on the Flutter module:
dependencies {
debugImplementation 'com.example2.flutter_pro_002:flutter_debug:1.0'
profileImplementation 'com.example2.flutter_pro_002:flutter_profile:1.0'
releaseImplementation 'com.example2.flutter_pro_002:flutter_release:1.0'
}
4. Add the `profile` build type:
android {
buildTypes {
profile {
initWith debug
}
}
}
To learn more, visit https://flutter.dev/go/build-aar
这就是已经成功打出aar包的表现,具体的包位置在:build\host\outputs\repo
中:
坑1解决完毕。
步骤2:集成FlutterBoost
由于我用的是FlutterSDK的2.5.3版本,所以我能匹配的最新flutterBoost版本是 3.1.3.
引入flutterBoost
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: '3.1.3'
记得 pub get
拉取依赖包
编辑dart代码
为了管理方便,我将flutterBoost相关的代码都集中到 boost_core.dart
中,代码如下:
iimport 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutterpro/test_route_widget.dart';
class BoostCore {
static void init() {
PageVisibilityBinding.instance
.addGlobalObserver(AppGlobalPageVisibilityObserver());
CustomFlutterBinding();
}
static Map<String, FlutterBoostRouteFactory> routerMap = {
'TopOrg': (RouteSettings settings, String? uniqueId) {
return PageRouteBuilder<dynamic>(
settings: settings,
pageBuilder: (_, __, ___) {
var arguments = settings.arguments;
var name = settings.name;
debugPrint("flutter收到的参数是: arguments:$arguments");
debugPrint("flutter收到的参数是: name:$name");
return const TestRouteWidget();
});
},
};
static Route<dynamic>? routeFactory(
RouteSettings settings, String? uniqueId) {
FlutterBoostRouteFactory? func = routerMap[settings.name!];
if (func == null) {
return PageRouteBuilder<dynamic>(
settings: settings,
pageBuilder: (_, __, ___) => const TestRouteWidget());
}
return func(settings, uniqueId);
}
}
class CustomFlutterBinding extends WidgetsFlutterBinding
with BoostFlutterBinding {}
class AppGlobalPageVisibilityObserver extends GlobalPageVisibilityObserver {
@override
void onPagePush(Route<dynamic> route) {
Logger.log(
'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageCreate route:${route.settings.name}');
}
@override
void onPageShow(Route<dynamic> route) {
Logger.log(
'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageShow route:${route.settings.name}');
}
@override
void onPageHide(Route<dynamic> route) {
Logger.log(
'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageHide route:${route.settings.name}');
}
@override
void onPagePop(Route<dynamic> route) {
Logger.log(
'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageDestroy route:${route.settings.name}');
}
@override
void onForeground(Route route) {
Logger.log(
'boost_lifecycle: AppGlobalPageVisibilityObserver.onForeground route:${route.settings.name}');
}
@override
void onBackground(Route<dynamic> route) {
Logger.log(
'boost_lifecycle: AppGlobalPageVisibilityObserver.onBackground route:${route.settings.name}');
}
}
class CustomInterceptor1 extends BoostInterceptor {
@override
void onPrePush(
BoostInterceptorOption option, PushInterceptorHandler handler) {
Logger.log('CustomInterceptor#onPrePush1~~~, $option');
// Add extra arguments
option.arguments!['CustomInterceptor1'] = "1";
super.onPrePush(option, handler);
}
@override
void onPostPush(
BoostInterceptorOption option, PushInterceptorHandler handler) {
Logger.log('CustomInterceptor#onPostPush1~~~, $option');
handler.next(option);
}
}
Logger.log('CustomInterceptor#onPostPush1~~~, $option');
handler.next(option);
}
}
然后是main.dart
:
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'boost_core.dart';
Future<void> main() async {
BoostCore.init();
// 实际上这里就是在启动引擎
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: child!);
},
home: FlutterBoostApp(BoostCore.routeFactory,
interceptors: [CustomInterceptor1()]),
);
}
}
最后是 一个 测试的 test_route_widget.dart
:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class TestRouteWidget extends StatelessWidget {
const TestRouteWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
);
}
}
然后再次尝试打aar,看是否能成功。
坑2
每一次你重新pub get,flutter项目的android临时文件都会重新刷新,所以坑1中的操作你得再做一次。修改之后,有可能无效,这时候重启工程试试看,不行就重启电脑,这个也属于AndroidStudio的bug。
一般重启工程之后就能顺利打出AAR。
拿到release版本的AAR
Flutter这端的工作已经完成,这个aar文件先放着。
Android侧
未完待续...
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfkgbee
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01