在前面的章节学习中咱们已经掌握了从最基本的
hello flutter
到各类基本Widget、各类布局的使用再到多页面切换路由的使用还有各类炫酷的提示跟dialog,还有关于网络请求库Dio的使用,至此咱们彻底可使用flutter去开发一款独立可运行的app了,可是基于现阶段flutter技术栈还不是太成熟,纯flutter项目上线风险仍是比较大,因此跨平台的混合开发模式天然仍是现阶段尝试flutter的主流方式,今天的分享我就跟你们一块把咱们写好的flutter项目打包成aar文件嵌入到现有的Android项目中去。html
flutter端项目我采用的是本专栏的实例代码项目:github.com/xiedong11/f…,Android端原生项目为新建的一个hello world项目,flutter端的相关配置我会上传到github仓库中,原生Android项目比较简单,我只在本博客中贴出部分关键代码java
flutter端项目工程目录 android
// 1. 生成aar产物,须要把`application`改成`library`
apply plugin: 'com.android.library'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// 2. flutter 做为寄存于其余app中的产物,因此不该该存在applicationId,因此注释掉该行.
//applicationId "com.zhuandian.flutterapp"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zhuandian.flutterapp">
<uses-permission android:name="android.permission.INTERNET" />
<!--1.项目做为子项目寄存于原生app中,不须要icon、label等属性,这里直接省去各类配置便可-->
<application>
<!--android:name="io.flutter.app.FlutterApplication"-->
<!--android:icon="@mipmap/ic_launcher"-->
<!--android:label="flutter_app">-->
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
<!--2.项目做为子项目寄存于原生app中,入口acitvity不须要配置LAUNCHER,否则应用集成到宿主app中,启动会在桌面上生成两个应用图标-->
<!--<meta-data-->
<!--android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"-->
<!--android:value="true" />-->
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--</intent-filter>-->
</activity>
<activity android:name=".SecondActivity"></activity>
</application>
</manifest>
复制代码
须要修改的地方,我都在源码里留注释了,这里就不展开赘述了,下面咱们来经过gradle得到编译好的aar
产物git
由于在build.gradle 中,咱们把apply plugin: 'com.android.application'
修改为了,apply plugin: 'com.android.library'
因此,如今经过Terminal中我执行gradlew assembleRelease
编译出的产物会有原来的apk变成aar文件,文件输出目录为项目根目录下的/bulid/app/outputs/aar
以下图所示: github
1.3.1 新建原生Android项目,我上述打包产出的aar文件做为依赖放入libs文件夹 bash
1.3.2 修改dependencies
节点下的fileTree
依赖配置,支持引入aar依赖支持网络
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
复制代码
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar']) ... } 复制代码
1.3.3 在原生Android项目中写一个简单的按钮测试flutter项目app
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//初始化flutter运行环境
FlutterMain.startInitialization(this)
tv_test_aar.setOnClickListener {
startActivity(Intent(this, com.zhuandian.flutterapp.MainActivity::class.java))
}
}
}
复制代码
至此,把flutter项目打包成aar导入到原生Android项目中的全部工程配置已经结束了,读者能够测试上上述整个过程;但有时候咱们的flutter项目并非单纯的flutter官方代码,开发过程当中少不了引入一些三方依赖,像上节课咱们讲到的Dio网络请求库,或者是经过
pubspec.yaml
引入的其余开源工具类,这种状况下,经过上边的配置方式,你会发现第三方的依赖代码是打不进aar包里的,下面咱们就讲解一下借助fat-aar
的形式把三方依赖代码打入aar包中去ide
经过上边的配置,咱们只能把纯flutter项目打包成aar文件,换句话说,若是咱们的flutter项目存在三方依赖是不能正常打包进flutter产物里的,这个时候咱们就须要经过在Android原生项目中引入fat-aar
配置,确保把flutter项目中的三方依赖正常打包进去flutter产物中去。工具
2.1修改项目工程目录的build.gradle文件,引入fat-aar支持
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
//引入fat-aar支持
classpath 'com.kezong:fat-aar:1.1.7'
}
}
复制代码
2.2 在上边第一部分配置app文件下build.gradle基础上,增长fat-aar相关配置,这里为了切换aar library运行环境,我引入isAarLibrary标志位做为切换环境开关,方便工程配置,具体代码以下:
//是否做为依赖
boolean isAarLibrary = true if (isAarLibrary) {
apply plugin: 'com.android.library'
} else {
apply plugin: 'com.android.application'
}
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
if (isAarLibrary) {
//引入fat-aar
apply plugin: 'com.kezong.fat-aar'
}
android {
compileSdkVersion 28
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
if (!isAarLibrary) {
applicationId "com.zhuandian.flutterapp"
}
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
implementation 'androidx.appcompat:appcompat:1.0.0'
if (isAarLibrary) {
//TODO 添加fat-aar处理flutter打包成aar中三方依赖
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, _ ->
println name embed project(path: ":$name", configuration: 'default') } } } 复制代码
2.3 AndroidManifest.xml清单文件中不须要增长额外配置,原生Android端唤起flutter项目aar包的方式也不须要修改,整个引入fat-aar的过程只是为了确保能把flutter项目中的三方依赖代码打入到flutter产物中去,因此关于flutter打包成aar的操做跟第一步保持一致就行,第二步的配置,只是为了确保flutter项目中的三方依赖能正常打包进flutter产物中去
效果图是我把本专栏的相关代码做为一个aar集成到一个新建的原生Android项目中,效果图以下:
项目的完整代码配置在github.com/xiedong11/f… 中,读者能够参考具体配置细节,笔者在写本篇博文打包aar时的flutter 环境stable版本为 flutter v1.9.1
,读者尽可能用官方稳定版的代码作测试。