Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter与Android混合编码配置笔记 #12

Open
qingmei2 opened this issue Jul 19, 2019 · 4 comments
Open

Flutter与Android混合编码配置笔记 #12

qingmei2 opened this issue Jul 19, 2019 · 4 comments
Labels
Flutter Flutter makes it easy and fast to build beautiful mobile apps.

Comments

@qingmei2
Copy link
Owner

Flutter与Android混合编码配置笔记

学习Flutter一小段时间,对纯Flutter项目有了一些基本的了解,但更趋近实际开发的应该是将Flutter模块作为一个依赖库添加到原生的Android项目中。

本文笔者将尝试分享个人针对FlutterAndroid混编时的配置步骤,以及踩坑过程。

一、初始化Flutter-Module

参考 官方文档 ,首先需要确认Flutter-Module依赖库文件夹的位置,简单来说,这里有两种方式:

  • 1.创建在项目的根目录下(内部);
  • 2.创建和项目文件夹的同一层级(外部),这也是官方推荐的方式。

其实这些方式没什么区别,但是个人更倾向于第二种,我们在项目文件夹的目录层级下对Flutter-Module文件夹进行 创建初始化

$ flutter create -t module module_flutter

成功后,Flutter-ModuleAndroid项目本身应该是这样的(红框内的两个项目):

二、配置Android项目

接下来我们需要将这个项目和刚刚创建的module-flutter进行依赖,我们先打开Android原生项目,并为项目根目录下的settings.gradle文件中添加如下配置:

setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        'module_flutter/.android/include_flutter.groovy'
))

如果module-flutter模块是创建在项目内部,那么需要稍微改一改:

setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.path,
        'module_flutter/.android/include_flutter.groovy'
))

然后,我们需要打开appbuild.gradle文件,添加对flutter的依赖:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.0'
    implementation 'androidx.annotation:annotation:1.0.0'

    ......

    implementation project(':flutter')
}

这样,对于简单的Android原生项目而言,Flutter已经配置成功了。

三、AndroidX的迁移

由于笔者的项目迁移了AndroidX, 但是低版本的Flutter命令生成的module默认依赖的是support包, 因此我们需要将默认support的依赖手动迁移到AndroidX

截止笔者发文前,FlutterV1.7已经提供了对AndroidX的支持,当创建 Flutter 项目的时候,你可以通过添加 --androidx 来确保生成的项目文件支持AndroidX,详情参考这里

手动迁移的方式有两种:

  • 1.通过Android Studio 自动迁移 过去。

首先通过Android Studio打开flutter-module,这时候是不能直接迁移AndroidX的,需要通过flutter - Open Android module in AS 方式新打开一个窗口。

这样编译成功后,就可以点击Refactor - Migrate to AndroidX进行迁移了,后续步骤网上有很多,不赘述。

  • 2.手动配置过去,这个方式也很简单,打开Flutter-build.gradle文件,对依赖进行更新:
android {
    //...
    defaultConfig {
      // ...
      testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
   }
   // ...
 }

dependencies {
    testImplementation 'junit:junit:4.12'
    implementation 'androidx.appcompat:appcompat:1.0.0'
    implementation 'androidx.annotation:annotation:1.0.0'

    // ...
}

手动配置网上有很多博客,不赘述。

需要注意的是,一定要保证Flutter模块中对AndroidX相关依赖的版本和实际原生项目中相关依赖的版本是一致的,否则可能会导致依赖冲突。

四、多模块项目的配置

上文说到,简单的项目已经配置完毕了,但是多模块的项目来说则稍显复杂,比如笔者的项目:

首先,需要在底层library(本文中是library-core)的build.gradle文件中添加对flutter的依赖:

dependencies {
    // ...
    api project(':flutter')
}

添加之后并进行同步,原生的项目就会对settings.gradle文件中指向的module-flutter文件夹进行依赖。

同步、编译成功后,我运行了项目,但我很快遇到了问题:

[ERROR:flutter/runtime/dart_vm_data.cc(19)] VM snapshot invalid and could not be inferred from settings.
[ERROR:flutter/runtime/dart_vm.cc(241)] Could not setup VM data to bootstrap the VM from.
[ERROR:flutter/runtime/dart_vm_lifecycle.cc(89)] Could not create Dart VM instance.
[FATAL:flutter/shell/common/shell.cc(218)] Check failed: vm. Must be able to initialize the VM.

五、ProductFlavors的坑

这个问题纠结了很久,最后在 这个issue中 找到了答案:

@yk3372 大佬提示,原来是以为项目中配置了ProductFlavors, 因此,Flutter模块中对应的build.gradle文件也需要进行对应的配置,比如这样:

buildTypes {
    release {}
    debug {}
}
flavorDimensions "environment"
productFlavors {
    dev {}
    qa {}
    prod {}
}

配置好之后,还需要手动将相关moduleProductFlavors配置相同,否则会提示一堆错误,比如我的一个原生的module依赖了fluttermodule,它们就必须都保持同一个状态:

???这是不是意味着所有的modulebuild.gradle都配置相同的productFlavors信息?

实践给予我答案,是的。

虽然折腾了很久,还好前人栽树,后人乘凉,解决了问题还是happy ending, Github大法好。

六、更多Flutter混编姿势

本文提供了 官方文档 提供混合开发的集成方式,实际上,国内很多大厂都分享过相关的技术文章,这里也一并放出来:


关于我

Hello,我是却把清梅嗅,如果您觉得文章对您有价值,欢迎 ❤️,也欢迎关注我的博客或者Github

如果您觉得文章还差了那么点东西,也请通过关注督促我写出更好的文章——万一哪天我进步了呢?

@qingmei2 qingmei2 added the Flutter Flutter makes it easy and fast to build beautiful mobile apps. label Jul 19, 2019
@xster
Copy link

xster commented Jul 25, 2019

哇,写的这么详细。辛苦了。这些问题应该马上在master上修复好了

flutter/flutter#35217
flutter/flutter#36805

非常感谢你对社区对贡献

@waitwalker
Copy link

waitwalker commented Jul 26, 2019

请问,我在Flutter module下的.android/app中的build.gradle中添加:

buildTypes {
        release {}
        debug {}
    }
    flavorDimensions "environment"
    productFlavors {
        develop {

        }
        production {

        }
    }

运行Flutter module,报的错:

[ERROR:flutter/runtime/dart_vm_data.cc(19)] VM snapshot invalid and could not be inferred from settings.
[ERROR:flutter/runtime/dart_vm.cc(241)] Could not setup VM data to bootstrap the VM from.
[ERROR:flutter/runtime/dart_vm_lifecycle.cc(89)] Could not create Dart VM instance.
[FATAL:flutter/shell/common/shell.cc(218)] Check failed: vm. Must be able to initialize the VM.

请教怎么解决,我主要做iOS,Android不懂,多谢指点一下!

@qingmei2
Copy link
Owner Author

qingmei2 commented Jul 26, 2019

@waitwalker

如果Android项目本身的app(而不是flutter-module/.android/app)中的build.gradle文件中没有配置productFlavors, 不需要在对应的 flutter-module/.android/app 中配置相同的productFlavors

如果你的项目是Android原生和Flutter混编,应该找Android开发的同事(或者看Android原生项目的源码),看一下build.gradle中的配置,保证对应的buildTypes配置和flutter-module/.android/app/build.gradle一致即可。

@junerver
Copy link

junerver commented Jan 21, 2021

@waitwalker

如果Android项目本身的app(而不是flutter-module/.android/app)中的build.gradle文件中没有配置productFlavors, 不需要在对应的 flutter-module/.android/app 中配置相同的productFlavors

如果你的项目是Android原生和Flutter混编,应该找Android开发的同事(或者看Android原生项目的源码),看一下build.gradle中的配置,保证对应的buildTypes配置和flutter-module/.android/app/build.gradle一致即可。

我保持了一致,并且在AS的Build Variants中也都选择成一致的,仍然出现了此问题,很困惑。
经过一些测试,我定位到应该是buildTypes的问题,我在项目中自定义了一些BuildTypes
比如:

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        ceshi {
            initWith debug
        }
    }
    flavorDimensions "environment"
    productFlavors {
        dev {
            dimension 'environment'
        }
        qa {
            dimension 'environment'
        }
        prod {
            dimension 'environment'
        }
    }

我将这些设置同步到了flutter模块中的gradle文件中,在选择debug时可以正常的调起flutter模块,但是如果我选择的是ceshi这个buildtype,仍然会出现

E/flutter: [ERROR:flutter/runtime/dart_vm_data.cc(18)] VM snapshot invalid and could not be inferred from settings.
    [ERROR:flutter/runtime/dart_vm.cc(250)] Could not setup VM data to bootstrap the VM from.
    [ERROR:flutter/runtime/dart_vm_lifecycle.cc(84)] Could not create Dart VM instance.
A/flutter: [FATAL:flutter/shell/common/shell.cc(274)] Check failed: vm. Must be able to initialize the VM.
A/libc: Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 5689 (ver.learnkotlin), pid 5689 (ver.learnkotlin)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Flutter Flutter makes it easy and fast to build beautiful mobile apps.
Projects
None yet
Development

No branches or pull requests

4 participants