当前位置:   article > 正文

Flutter Boost 3.0混合开发_ext.kotlin_version

ext.kotlin_version

一、Flutter Boost简介

家喻户晓,Flutter是一个由C++实现的Flutter Engine和由Dart实现的Framework组成的跨平台技术框架。其中,Flutter Engine负责线程治理、Dart VM状态治理以及Dart代码加载等工作,而Dart代码所实现的Framework则负责下层业务开发,如Flutter提供的组件等概念就是Framework的领域。

随着Flutter的倒退,国内越来越多的App开始接入Flutter。为了升高危险,大部分App采纳渐进式形式引入Flutter,在App里选几个页面用Flutter来编写,但都碰到了雷同的问题,在原生页面和Flutter页面共存的状况下,如何治理路由,以及原生页面与Flutter页面之间的切换和通信都是混合开发中须要解决的问题。然而,官网没有提供明确的解决方案,只是在混合开发时,官网倡议开发者,应该应用同一个引擎反对多窗口绘制的能力,至多在逻辑上做到FlutterViewController是共享同一个引擎外面的资源。换句话说,官网心愿所有的绘制窗口共享同一个主Isolate,而不是呈现多个主Isolate的状况。不过,对于当初曾经呈现的多引擎模式问题,Flutter官网也没有提供好的解决方案。除了内存耗费重大外,多引擎模式还会带来如下一些问题。

  • 冗余资源问题。多引擎模式下每个引擎的Isolate是互相独立的,尽管在逻辑上这并没有什么害处,然而每个引擎底层都保护了一套图片缓存等比拟耗费内存的对象,因而设施的内存耗费是十分重大的。
  • 插件注册问题。在Flutter插件中,消息传递须要依赖Messenger,而Messenger是由FlutterViewController去实现的。如果一个利用中同时存在多个FlutterViewController,那么插件的注册和通信将会变得凌乱且难以保护。
  • Flutter组件和原生页面的差异化问题。通常,Flutter页面是由组件形成的,原生页面则是由ViewController或者Activity形成的。逻辑上来说,咱们心愿打消Flutter页面与原生页面的差别,否则在进行页面埋点和其它一些操作时减少一些额定的工作量。
  • 减少页面通信的复杂度。如果所有的Dart代码都运行在同一个引擎实例中,那么它们会共享同一个Isolate,能够用对立的框架实现组件之间的通信,然而如果存在多个引擎实例会让Isolate的治理变得更加简单。

如果不解决多引擎问题,那么混合我的项目的导航栈如下图所示。

目前,对于原生工程混编Flutter工程呈现的多引擎模式问题,国内次要有两种解决方案,一种是字节跳动的批改Flutter Engine源码计划,另一种是闲鱼开源的FlutterBoost。因为字节跳动的混合开发的计划没有开源,所以当初能应用的就剩下FlutterBoost计划。

FlutterBoost是闲鱼技术团队开发的一个可复用页面的插件,旨在把Flutter容器做成相似于浏览器的加载计划。为此,闲鱼技术团队为心愿FlutterBoost能实现如下的基本功能:

  • 可复用的通用型混合开发计划。
  • 反对更加简单的混合模式,比方反对Tab切换的场景。
  • 无侵入性计划,应用时不再依赖批改Flutter的计划。
  • 反对对页面生命周期进行对立的治理。
  • 具备对立明确的设计概念。

并且,最近Flutter Boost降级了3.0版本,并带来了如下的一些更新:

  • 不侵入引擎,兼容Flutter的各种版本,Flutter sdk的降级不须要再降级FlutterBoost,极大升高降级老本。
  • 不辨别Androidx和Support分支。
  • 简化架构和接口,和FlutterBoost2.0比,代码缩小了一半。
  • 双端对立,包含接口和设计上的对立。
  • 反对关上Flutter页面,不再关上容器场景。
  • 页面生命周期变动告诉更不便业务应用。
  • 解决了2.0中的遗留问题,例如,Fragment接入艰难、页面敞开后不能传递数据、dispose不执行,内存占用过低等。

二、Flutter Boost集成

在原生我的项目中集成Flutter Boost只须要将Flutter Boost看成是一个插件工程即可。和其余Flutter插件的集成形式一样,应用FlutterBoost之前须要先增加依赖。应用Android Studio关上混合工程的Flutter工程,在pubspec.yaml中增加FlutterBoost依赖插件,如下所示。

  1. flutter_boost:
  2. git:
  3. url: 'https://github.com/alibaba/flutter_boost.git'
  4. ref: 'v3.0-hotfixes'

须要阐明的是,此处的所依赖的FlutterBoost的版本与Flutter的版本是对应的,如果不对应应用过程中会呈现版本不匹配的谬误。而后,应用flutter packages get命令将FlutterBoost插件拉取到本地。

2.1 Android集成

应用Android Studio关上新建的原生Android工程,在原生Android工程的settings.gradle文件中增加如下代码。

  1. setBinding(new Binding([gradle: this]))
  2. evaluate(new File(
  3. settingsDir.parentFile,
  4. 'flutter_library/.android/include_flutter.groovy'))

而后,关上原生Android工程app目录下的build.gradle文件,持续增加如下依赖脚本。

  1. dependencies {
  2. implementation project(':flutter_boost')
  3. implementation project(':flutter')
  4. }

从新编译构建原生Android工程,如果没有任何谬误则阐明Android胜利了集成FlutterBoost。应用Flutter Boost 之前,须要先执行初始化。关上原生Android工程,新建一个继承FlutterApplication的Application,而后在onCreate()办法中初始化FlutterBoost,代码如下。

  1. public class MyApplication extends FlutterApplication {
  2. @Override
  3. public void onCreate() {
  4. super.onCreate();
  5. FlutterBoost.instance().setup(this, new FlutterBoostDelegate() {
  6. @Override
  7. public void pushNativeRoute(String pageName, HashMap<String, String> arguments) {
  8. Intent intent = new Intent(FlutterBoost.instance().currentActivity(), NativePageActivity.class);
  9. FlutterBoost.instance().currentActivity().startActivity(intent);
  10. }
  11. @Override
  12. public void pushFlutterRoute(String pageName, HashMap<String, String> arguments) {
  13. Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class, FlutterBoost.ENGINE_ID)
  14. .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.opaque)
  15. .destroyEngineWithActivity(false)
  16. .url(pageName)
  17. .urlParams(arguments)
  18. .build(FlutterBoost.instance().currentActivity());
  19. FlutterBoost.instance().currentActivity().startActivity(intent);
  20. }
  21. },engine->{
  22. engine.getPlugins();
  23. } );
  24. }
  25. }

而后,关上原生Android工程下的AndroidManifest.xml文件,将Application替换成自定义的MyApplication,如下所示。

  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. package="com.idlefish.flutterboost.example">
  4. <application
  5. android:name="com.idlefish.flutterboost.example.MyApplication"
  6. android:label="flutter_boost_example"
  7. android:icon="@mipmap/ic_launcher">
  8. <activity
  9. android:name="com.idlefish.flutterboost.containers.FlutterBoostActivity"
  10. android:theme="@style/Theme.AppCompat"
  11. android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
  12. android:hardwareAccelerated="true"
  13. android:windowSoftInputMode="adjustResize" >
  14. <meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background"/>
  15. </activity>
  16. <meta-data android:name="flutterEmbedding"
  17. android:value="2">
  18. </meta-data>
  19. </application>
  20. </manifest>

因为Flutter Boost 是以插件的形式集成到原生Android我的项目的,所以咱们能够在Native 关上和敞开Flutter模块的页面。

  1. FlutterBoost.instance().open("flutterPage",params);
  2. FlutterBoost.instance().close("uniqueId");

而Flutter Dart的应用如下。首先,咱们能够在main.dart文件的程序入口main()办法中进行初始化。

  1. void main() {
  2. runApp(MyApp());
  3. }
  4. class MyApp extends StatefulWidget {
  5. @override
  6. _MyAppState createState() => _MyAppState();
  7. }
  8. class _MyAppState extends State<MyApp> {
  9. static Map<String, FlutterBoostRouteFactory>
  10. routerMap = {
  11. '/': (settings, uniqueId) {
  12. return PageRouteBuilder<dynamic>(
  13. settings: settings, pageBuilder: (_, __, ___)
  14. => Container());
  15. },
  16. 'embedded': (settings, uniqueId) {
  17. return PageRouteBuilder<dynamic>(
  18. settings: settings,
  19. pageBuilder: (_, __, ___) =>
  20. EmbeddedFirstRouteWidget());
  21. },
  22. 'presentFlutterPage': (settings, uniqueId) {
  23. return PageRouteBuilder<dynamic>(
  24. settings: settings,
  25. pageBuilder: (_, __, ___) =>
  26. FlutterRouteWidget(
  27. params: settings.arguments,
  28. uniqueId: uniqueId,
  29. ));
  30. }};
  31. Route<dynamic> routeFactory(RouteSettings settings, String uniqueId) {
  32. FlutterBoostRouteFactory func =routerMap[settings.name];
  33. if (func == null) {
  34. return null;
  35. }
  36. return func(settings, uniqueId);
  37. }
  38. @override
  39. void initState() {
  40. super.initState();
  41. }
  42. @override
  43. Widget build(BuildContext context) {
  44. return FlutterBoostApp(
  45. routeFactory
  46. );
  47. }

当然,还能够监听页面的生命周期,如下所示。

  1. class SimpleWidget extends StatefulWidget {
  2. final Map params;
  3. final String messages;
  4. final String uniqueId;
  5. const SimpleWidget(this.uniqueId, this.params, this.messages);
  6. @override
  7. _SimpleWidgetState createState() => _SimpleWidgetState();
  8. }
  9. class _SimpleWidgetState extends State<SimpleWidget>
  10. with PageVisibilityObserver {
  11. static const String _kTag = 'xlog';
  12. @override
  13. void didChangeDependencies() {
  14. super.didChangeDependencies();
  15. print('$_kTag#didChangeDependencies, ${widget.uniqueId}, $this');
  16. }
  17. @override
  18. void initState() {
  19. super.initState();
  20. PageVisibilityBinding.instance.addObserver(this, ModalRoute.of(context));
  21. print('$_kTag#initState, ${widget.uniqueId}, $this');
  22. }
  23. @override
  24. void dispose() {
  25. PageVisibilityBinding.instance.removeObserver(this);
  26. print('$_kTag#dispose, ${widget.uniqueId}, $this');
  27. super.dispose();
  28. }
  29. @override
  30. void onForeground() {
  31. print('$_kTag#onForeground, ${widget.uniqueId}, $this');
  32. }
  33. @override
  34. void onBackground() {
  35. print('$_kTag#onBackground, ${widget.uniqueId}, $this');
  36. }
  37. @override
  38. void onAppear(ChangeReason reason) {
  39. print('$_kTag#onAppear, ${widget.uniqueId}, $reason, $this');
  40. }
  41. void onDisappear(ChangeReason reason) {
  42. print('$_kTag#onDisappear, ${widget.uniqueId}, $reason, $this');
  43. }
  44. @override
  45. Widget build(BuildContext context) {
  46. return Scaffold(
  47. appBar: AppBar(
  48. title: Text('tab_example'),
  49. ),
  50. body: SingleChildScrollView(
  51. physics: BouncingScrollPhysics(),
  52. child: Container(
  53. child: Column(
  54. crossAxisAlignment: CrossAxisAlignment.start,
  55. children: <Widget>[
  56. Container(
  57. margin: const EdgeInsets.only(top: 80.0),
  58. child: Text(
  59. widget.messages,
  60. style: TextStyle(fontSize: 28.0, color: Colors.blue),
  61. ),
  62. alignment: AlignmentDirectional.center,
  63. ),
  64. Container(
  65. margin: const EdgeInsets.only(top: 32.0),
  66. child: Text(
  67. widget.uniqueId,
  68. style: TextStyle(fontSize: 22.0, color: Colors.red),
  69. ),
  70. alignment: AlignmentDirectional.center,
  71. ),
  72. InkWell(
  73. child: Container(
  74. padding: const EdgeInsets.all(8.0),
  75. margin: const EdgeInsets.all(30.0),
  76. color: Colors.yellow,
  77. child: Text(
  78. 'open flutter page',
  79. style: TextStyle(fontSize: 22.0, color: Colors.black),
  80. )),
  81. onTap: () => BoostNavigator.of().push("flutterPage",
  82. arguments: <String, String>{'from': widget.uniqueId}),
  83. )
  84. Container(
  85. height: 300,
  86. width: 200,
  87. child: Text(
  88. '',
  89. style: TextStyle(fontSize: 22.0, color: Colors.black),
  90. ),
  91. )
  92. ],
  93. ))),
  94. );
  95. }
  96. }

而后,运行我的项目,就能够从原生页面跳转到Flutter页面,如下图所示成果。

2.2 iOS集成

和Android的集成步骤一样,应用Xcode关上原生iOS工程,而后在iOS的AppDelegate文件中初始化Flutter Boost ,如下所示。

  1. @interface AppDelegate ()
  2. @end
  3. @implementation AppDelegate
  4. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  5. {
  6. MyFlutterBoostDelegate* delegate=[[MyFlutterBoostDelegate alloc ] init];
  7. [[FlutterBoost instance] setup:application delegate:delegate callback:^(FlutterEngine *engine) {
  8. } ];
  9. return YES;
  10. }
  11. @end

上面是自定义的FlutterBoostDelegate的代码,如下所示。

  1. @interface MyFlutterBoostDelegate : NSObject<FlutterBoostDelegate>
  2. @property (nonatomic,strong) UINavigationController *navigationController;
  3. @end
  4. @implementation MyFlutterBoostDelegate
  5. - (void) pushNativeRoute:(FBCommonParams*) params{
  6. BOOL animated = [params.arguments[@"animated"] boolValue];
  7. BOOL present= [params.arguments[@"present"] boolValue];
  8. UIViewControllerDemo *nvc = [[UIViewControllerDemo alloc] initWithNibName:@"UIViewControllerDemo" bundle:[NSBundle mainBundle]];
  9. if(present){
  10. [self.navigationController presentViewController:nvc animated:animated completion:^{
  11. }];
  12. }else{
  13. [self.navigationController pushViewController:nvc animated:animated];
  14. }
  15. }
  16. - (void) pushFlutterRoute:(FBCommonParams*)params {
  17. FlutterEngine* engine = [[FlutterBoost instance ] getEngine];
  18. engine.viewController = nil;
  19. FBFlutterViewContainer *vc = FBFlutterViewContainer.new ;
  20. [vc setName:params.pageName params:params.arguments];
  21. BOOL animated = [params.arguments[@"animated"] boolValue];
  22. BOOL present= [params.arguments[@"present"] boolValue];
  23. if(present){
  24. [self.navigationController presentViewController:vc animated:animated completion:^{
  25. }];
  26. }else{
  27. [self.navigationController pushViewController:vc animated:animated];
  28. }
  29. }
  30. - (void) popRoute:(FBCommonParams*)params
  31. result:(NSDictionary *)result{
  32. FBFlutterViewContainer *vc = (id)self.navigationController.presentedViewController;
  33. if([vc isKindOfClass:FBFlutterViewContainer.class] && [vc.uniqueIDString isEqual: params.uniqueId]){
  34. [vc dismissViewControllerAnimated:YES completion:^{}];
  35. }else{
  36. [self.navigationController popViewControllerAnimated:YES];
  37. }
  38. }
  39. @end

如果要在原生iOS代码中关上或敞开Flutter页面,能够应用上面的形式。

  1. [[FlutterBoost instance] open:@"flutterPage" arguments:@{@"animated":@(YES)} ];
  2. [[FlutterBoost instance] open:@"secondStateful" arguments:@{@"present":@(YES)}];

三、Flutter Boost架构

对于混合工程来说,原生端和Flutter端对于页面的定义是不一样的。对于原生端而言,页面通常指的是一个ViewController或者Activity,而对于Flutter来说,页面通常指的是Flutter组件。FlutterBoost框架所要做的就是对立混合工程中页面的概念,或者说弱化Flutter组件对应容器页面的概念。换句话说,当有一个原生页面存在的时候,FlutteBoost就能保障肯定有一个对应的Flutter的容器页面存在。

FlutterBoost框架其实就是由原生容器通过音讯驱动Flutter页面容器,从而达到原生容器与Flutter容器同步的目标,而Flutter渲染的内容是由原生容器去驱动的,上面是Flutter Boost 给的一个Flutter Boost 的架构示意图。


能够看到,Flutter Boost插件分为平台和Dart两端,两头通过Message Channel连贯。平台侧提供了Flutter引擎的配置和治理、Native容器的创立/销毁、页面可见性变动告诉,以及Flutter页面的关上/敞开接口等。而Dart侧除了提供相似原生Navigator的页面导航接口的能力外,还负责Flutter页面的路由治理。

总的来说,正是基于共享同一个引擎的计划,使得FlutterBoost框架无效的解决了多引擎的问题。简略来说,FlutterBoost在Dart端引入了容器的概念,当存在多个Flutter页面时,FlutterBoost不须要再用栈的构造去保护现有页面,而是应用扁平化键值对映射的模式去保护以后所有的页面,并且每个页面领有一个惟一的id

四、FlutterBoost3.0更新

4.1 不入侵引擎

为了解决官网引擎复用引起的问题,FlutterBoost2.0拷贝了Flutter引擎Embedding层的一些代码进行革新,这使得前期的降级老本极高。而FlutterBoost3.0采纳继承的形式扩大FlutterActivity/FlutterFragment等组件的能力,并且通过在适当机会给Dart侧发送appIsResumed音讯解决引擎复用时生命周期事件错乱导致的页面卡死问题,并且,FlutterBoost 3.0 也兼容最新的官网公布的 Flutter 2.0。

4.2 不辨别Androidx和Support分支

FlutterBoost2.0通过本人实现FlutterActivityAndFragmentDelegate.Host接口来扩大FlutterActivity和FlutterFragment的能力,而getLifecycle是必须实现的接口,这就导致对androidx的依赖。这也是为什么FlutterBoostView的实现没有被放入FlutterBoost3.0插件中的起因。而FlutterBoost3.0通过继承的形式扩大FlutterActivity/FlutterFragment的能力的额定收益就是,能够做到不依赖androidx。

4.3 双端设计对立,接口对立

很多Flutter开发者只会一端,只会Android 或者只会IOS,但他须要接入双端,所以双端对立能升高他的 学习老本和接入老本。FlutterBoost3.0,在设计上 Android和IOS都做了对齐,特地接口上做到了参数级的对齐。

4.4 反对 【关上flutter页面不再关上容器】 场景

在Flutter模块外部,Flutter 页面跳转Flutter 页面是能够不须要再关上Flutter容器的,不关上容器,能节俭内存开销。在FlutterBoost3.0上,关上容器和不关上容器的区别体现在用户接口上仅仅是withContainer参数是否为true就好。

  1. InkWell(
  2. child: Container(
  3. color: Colors.yellow,
  4. child: Text(
  5. '关上内部路由',
  6. style: TextStyle(fontSize: 22.0, color: Colors.black),
  7. )),
  8. onTap: () => BoostNavigator.of().push("flutterPage",
  9. arguments: <String, String>{'from': widget.uniqueId}),
  10. ),
  11. InkWell(
  12. child: Container(
  13. color: Colors.yellow,
  14. child: Text(
  15. '关上外部路由',
  16. style: TextStyle(fontSize: 22.0, color: Colors.black),
  17. )),
  18. onTap: () => BoostNavigator.of().push("flutterPage",
  19. withContainer: true,
  20. arguments: <String, String>{'from': widget.uniqueId}),
  21. )

4.5 生命周期的精准告诉

在FlutterBoost2.0上,每个页面都会收到页面生命周期告诉,而FlutterBoost3.0只会告诉页面可见性理论产生了变动的页面,接口也更合乎flutter的设计。

4.6 其余Issue

除了下面的一些个性外,Flutter Boost 3.0版本还解决了如下一些问题:

  • 页面敞开后参数的传递,之前只有iOS反对,android不反对,目前在dart侧实现,Ios 和Android 都反对。
  • 解决了Android 状态栏字体和色彩问题。
  • 解决了页面回退willpopscope不起作用问题。
  • 解决了不在栈顶的页面也收到生命周期回调的问题
  • 解决了屡次setState耗性能问题。
  • 提供了Framgent 多种接入形式的Demo,不便tab 场景的接入。
  • 生命周期的回调代码,能够用户代码外面with的形式接入,应用更简略。
  • 全面简化了,接入老本,包含 dart侧,android侧和ios
  • 丰盛了demo,蕴含了根本场景,不便用户接入 和测试回归

集成过程中可能出现的问题

在下面文章中,详细讲述了flutter_boost老版本的接入方式, https://blog.csdn.net/lzw398756924/article/details/113245174https://blog.csdn.net/lzw398756924/article/details/113245174

问题1——为什么我的Flutter Module中怎么没有.android和.ios目录? 

原来这个跟flutter module的创建方式有关。

创建flutter module的时候不要用android studio创建,要用命令创建:

flutter create -t module flutter_module

在flutter_module工程中添加执行如下命令,拉取flutter依赖:

flutter packages get

注意:这一步比较重要,flutter会帮我们执行创建.android、.ios等默认的文件目录。这些文件目录中包含了后续步骤需要使用的include_flutter.groovy等文件。

 当然大家会发现通过命令创建的flutter_module也有个问题,没有android和ios的目录,这个就需要我们使用android studio在其他目录下创建一个同名flutter_module工程,然后把android和ios的目录全部拷贝到原来的工程下即可。

2.Exception: Gradle build failed to produce an .apk file. It's likely that this file was generated under /Users/用户/Documents/FlutterProjects/flutter_module/build, but the tool couldn't find it.

原因分析参考:【原创】Exception: Gradle build failed to produce an .apk file. It's likely that this file was genera... - 简书为了解决这个问题我刚开始的方向是错了,包括群里问人,发issues,谷歌搜索 https://github.com/flutter/flutter/issues/95722[...https://www.jianshu.com/p/a452270dbb57

pubspec.yaml里面的module注释掉即可

  #module:
  #  androidX: true
  #  androidPackage: com.example.my_flutter
  #  iosBundleIdentifier: com.example.myFlutter

注意:这个问题只会在flutter run的时候会出现,也就是单独运行flutter工程时出现。注释掉module模块后,工程下的.android、.ios目录神奇的消失了,取消注释module,flutter pub get后就又自动出现.android、.ios目录了,如果是混合开发,从Android工程侧运行工程,则不能注释module的配置。

3. Error:Kotlin: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.16.

解决方案:

方案1:

在您的项目级 gradle 文件中,只需将 ext.kotlin.version 从您拥有的任何版本增加到“1.4.32”或任何可用的最新版本。
路径:/android/build.gradle

  1. buildscript {
  2. ext.kotlin_version = '1.4.32'
  3. repositories {
  4. google()
  5. jcenter()
  6. }
  7. dependencies {
  8. classpath 'com.android.tools.build:gradle:4.0.2'
  9. classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  10. }
  11. }
  12. allprojects {
  13. repositories {
  14. google()
  15. jcenter()
  16. }
  17. }

4.Minimum supported Gradle version is 6.1.1. Current version is 5.6.4.

解决方法:

Minimum supported Gradle version is 6.1.1. Current version is 5.6.4._whjk20的专栏-CSDN博客Android Studio 导入项目,Gradle 同步时,提示以下错误:Minimum supported Gradle version is 6.1.1. Current version is 5.6.4.Please fix the project's Gradle settings.Fix Gradle wrapper and re-import projectOpen Gradle wrapper propertiesGradle settings其实就是你导入的项目使用的Ahttps://blog.csdn.net/whjk20/article/details/108545522

5.ext.kotlin_version = '<latest-version>'  .

  1. ┌─ Flutter Fix ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  2. │ [!] Your project requires a newer version of the Kotlin Gradle plugin.                                                                                                                     │
  3. │ Find the latest version on https://kotlinlang.org/docs/gradle.html#plugin-and-versions, then update /Users/用户/Documents/FlutterProjects/hubble_flutter_module/android/build.gradle: │
  4. │ ext.kotlin_version = '<latest-version>'                                                                                                                                                    │
  5. └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  6. Exception: Gradle task assembleDebug failed with exit code 1

解决方案:

  1. buildscript {
  2. ext.kotlin_version = '1.5.0' //use latest
  3. ...
  4. }
  5. dependencies {
  6. classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  7. ...
  8. }

1.5.*以上的就可以,不必使用最新的kotlin版本

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/308555
推荐阅读
相关标签
  

闽ICP备14008679号