了解一下如何在 Android 原生项目中集成 Flutter
在原生项目根目录执行命令
flutter create -t module --org {package_name} {module_name}
// 此处 module_name 的命令遵循 Android 子 module 的命名即可。不能有中划线。
// 比如,
flutter create -t module --org com.engineer.mini.flutter flutter_sub
// 此处 module_name 的命令遵循 Android 子 module 的命名即可。不能有中划线。
// 比如,
flutter create -t module --org com.engineer.mini.flutter flutter_sub
</pre>
结果
<pre class="prettyprint hljs groovy" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">Creating project sub_flutter...
sub_flutter/test/widget_test.dart (created)
sub_flutter/sub_flutter.iml (created)
sub_flutter/.gitignore (created)
sub_flutter/.metadata (created)
sub_flutter/pubspec.yaml (created)
sub_flutter/README.md (created)
sub_flutter/lib/main.dart (created)
sub_flutter/sub_flutter_android.iml (created)
sub_flutter/.idea/libraries/Dart_SDK.xml (created)
sub_flutter/.idea/modules.xml (created)
sub_flutter/.idea/workspace.xml (created)
Running "flutter pub get" in sub_flutter... 1,054ms
Wrote 11 files.
</pre>
最终生成了以上文件,注意这里最后?自动执行了 flutter pub get?的命令。关于 flutter pub get 具体做了什么,可以参考后面的。
这里在项目根目录创建子 module 只是为了把代码放在一个仓库,方便维护,理论上可以放在硬盘的任何位置。
在配置 settings.gradle 之前先来简单回顾一下关于 Gradle 的一些基础知识。
如果你了解过 Gradle 相关的配置的话,一定会看到一个概念,就是?约定优于配置?,什么意思呢,按照面向对象的思路来理解,每一个工程是一个巨大的 Project 类,整个类里有很多的属性。而我们创建的每一个项目其实就是一个具体的 Project 对象(也就是实例).约定优于配置的意思,就是在 project 实例化的时候,其内部的属性已经有了默认值。那么我们怎么知道有哪些默认值呢?在项目根目录执行
./gradlew properties
就可以得到整个 Project 的一些默认配置,比如(此处节选部分结果)
------------------------------------------------------------
Root project
------------------------------------------------------------
allprojects: [root project 'MiniApp', project ':app', project ':thirdlib']
android.agp.version.check.performed: true
android.enableJetifier: true
android.enableR8: true
android.enableR8.libraries: true
android.useAndroidX: true
buildDir: /Users/username/Documents/mygithub/MinApp/build
buildFile: /Users/username/Documents/mygithub/MinApp/build.gradle
projectDir: /Users/username/Documents/mygithub/MinApp
rootDir: /Users/username/Documents/mygithub/MinApp
rootProject: root project 'MiniApp'
这里当前有一些是我们配置的,比如 useAndroidX,但也有一些是约定的,比如 对于整个 project 来说 buildDir 就是项目根目录的 build 文件夹等。
执行
./gradlew :app:properties
节选部分结果
buildDir: /Users/username/Documents/mygithub/MinApp/app/build
buildFile: /Users/username/Documents/mygithub/MinApp/app/build.gradle
就会得到关于 app 整个 module 现阶段的一些配置信息,当然这些配置信息除了约定的,还有你自己配置的,比如 buildToolsVersion ,签名等相关信息。可以看到 buildDir 和整个 project 的是不一样的。
回到主题, 看看如何把我们刚才创建的 sub_flutter 模块集成到项目中。(严格来说并不是集成 sub_flutter 模块,因为他只是一个 flutter 的模块,而在 Android 主项目只能集成子 Android module,那么具体改怎么做呢,下面就来看看其中的奥秘)
按照官方的操作方法,会要求我们添加以下配置到 settings.gradle 中。
// Include the host app project.
include ':app' // assumed existing content
setBinding(new Binding([gradle: this])) // new
evaluate(new File( // new
settingsDir.parentFile, // new
'my_flutter/.android/include_flutter.groovy' // new
)) // new
首先看看 这里的 settingsDir 的值。在 settings.gradle 中直接添加
println "settings.dir=" + settingsDir
println "settings.dir.parent=" + settingsDir.parent
sync 之后就会看到输出
settings.dir=/Users/username/Documents/mygithub/MinApp
settings.dir.parent=/Users/username/Documents/mygithub
所以,上面的配置信息,就是说结合 settings 所在目录的父目录和我们配置的目录结合,找到一个名为 include_flutter.groovy 的文件,然后去执行他。
前面说了,创建子 module 的时候,可以是在项目根目录,也可以是在其他位置,如果是在其他位置,这里的 my_flutter 可以替换为你创建目录的绝对路劲。
这里是在根目录直接创建的,那么以上的配置就可以简化为
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir, 'sub_flutter/.android/include_flutter.groovy'))
include ':sub_flutter'
#### 关于 include_flutter.groovy
上面说了,settings.gradle 的配置,其实就是去执行 include_flutter.groovy 这个文件,可以简单看一下这个文件
def scriptFile = getClass().protectionDomain.codeSource.location.toURI()
def flutterProjectRoot = new File(scriptFile).parentFile.parentFile
gradle.include ":flutter"
gradle.project(":flutter").projectDir = new File(flutterProjectRoot, ".android/Flutter")
def localPropertiesFile = new File(flutterProjectRoot, ".android/local.properties")
def properties = new Properties()
assert localPropertiesFile.exists(), ":exclamation:?The Flutter module doesn't have a `$localPropertiesFile` file." +
"\nYou must run `flutter pub get` in `$flutterProjectRoot`."
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
gradle.apply from: "$flutterSdkPath/packages/flutter_tools/gradle/module_plugin_loader.gradle"
.android 其实就是一个 Android 项目,他包含一个 Flutter 文件夹,这 Flutter 是一个 library 类型的 Android module ,这个一点从他的 build.gradle 文件就可以看出。 include_flutter.groovy 所做的事情,就是将当前 library 命名为 flutter 的一个 moudle。然后检查项目中 local.properties 中 sdk 的相关配置,最后去执行 FlutterSDK 的中 gradle 脚本,这里具体的分析就不再展开了。
也就是说,现在有一个名为 flutter 的 Android Library Module 。这个 module 包含 flutter 的所有配置。我们如果依赖了这个 module ,那么就相当于是依赖了 Flutter .
最后在原生项目的 application-module 的 build.gradle 的 dependencies 闭包中添加
implementation project(':flutter')
至此,原生项目已经有了 Flutter 的依赖,可以使用 Flutter 的 View 了。
至此,现在的原生项目就包含 Flutter SDK 的所有依赖了,UI 相关的内容,改怎么写还是用 dart 在 main.dart 中写,然后我们就可以把这个 dart 渲染出来的内容按照 Activity 、Fragment 或 View 的形式添加到已有的项目中了。
flutter pub get 或者 pub get 是在做 flutter 的时候在使用第三方 lib 或版本更新的时候经常会使用一个命令,通过这个命令会拉取相关的依赖,其实这个命令还会自动生成 Android 和 iOS 的原生项目。比如在我们创建就的 sub_flutter 模块中,均自动生成了 .android 和 .ios 的原生项目目录。同时这两个目录都是点打头的,那么一般情况下就是隐藏文件,同时通过 .gitignore 文件也可以看到,对于 flutter module 形式来说,这两个文件夹都是被忽略的,毕竟 flutter module 的核心,还是为了方便以 module 的形式集成到原生的项目中,内部的两个原生目录,一方面是为了方便集成,另一方面是便于直接运行执行 hot-reload 的调试。
Linux下查询进程占用的内存方法总结,假设现在有一个「php-cgi」的进程 ,进程id...
WebService端代码 复制代码 代码如下: /// summary /// 上传文件到远程服务器 //...
对于图片,首先我们先想到是背景图片。因为我们许许多的装饰都是用背景图片来实...
PHP中,终止脚本运行有三种方式:主脚本程序中使用return、脚本中使用exit()、di...
XML的未来 现在你已经知道XML。确实,结构有点复杂,而且DTD有各种可 以定义文档...
写在前面 本文包括浏览器调试,不包括web移动端调试。 本文调试均在chrome浏览器...
本文转载自微信公众号「 jinjunzhu」,作者 jinjunzhu 。转载本文请联系 jinjunz...
有的时候,我们在网页中会用到复选框,也就是多选框,当用户提交输入信息的时候...
项目简介 Tendis是腾讯互娱CROS DBA团队 腾讯云数据库团队自主设计和研发的分布...
壹 引 我记得在17年使用atom编辑器的时候,使用过一款打字特效的插件,只要我们...