flutter工程化踩坑实录

2,007 阅读2分钟

一.app组件化架构设计

app_architecture

二.flutter工程结构

flutter_project

  • dartModule

它是一个flutter module,它包含dart侧的业务代码和一些抽象出来的dart plugins/packages.编译产物aar/framework,

  • flutter core

维护flutter源码,用于支撑后续对于flutter engine的修改,编译产生flutterEngine和flutter framework.编译产物aar/framework,

  • fluttercoreWrapper

flutter打包出来的aar/framework的包装工程,它包含flutterEngine和flutter framework。编译产物aar/framework,

  • flutterNativeBridge

flutter 与 native交互的中间组件,目前包含了flutterboost 与待完成的MessageChannel。编译产物aar/framework,

  • dartDebugger

本地dart调试工程,解决dart开发与调试。它是一个flutter app工程,依赖native和dart module。

三.工程化过程

一.新建flutter 模块工程

flutter create -t module --org com.huya.hive fluttercore

工程结构如图所示: flutter模块工程结构

它包含一个.android工程,一个.ios的工程,这两个工程可以通过在fluttercore上右键打开,可以用于调试dart代码

二.构建aar业务模块包

这里构建的包不包含flutter framework和flutter engine的代码。

flutter build aar --no-debug --no-profile --no-pub --target-platform android-arm,android-arm64 --build-number 1.0.1

flutter build ios-framework --no-debug --no-profile --no-pub


构建出来的aar结构如图: 构建flutter模块aar

构建结果中包含的libapp.so中包含了dart代码

三.新建android 普通工程fluttercoreWrapper

在工程中新建模块fluttercore

项目级的build.gradle中增加fat-aar的依赖

classpath 'com.github.kezong:fat-aar:1.3.6'

添加fat-aar的原因是上一步构建出来的aar仅仅包含了dar代码不包含依赖的库,libFlutter.so(包含不同的eabi)和flutter_embedding_release.jar,因此这一步把两个库打进去。

注意这两个文件都是从远程服务器下载的,这里我卡了很久,一直以为是本地构建生成的,实际上不是,下载仓库地址为

maven {
   url "https://storage.googleapis.com/download.flutter.io"
}

完整的项目级build.gradle如下所示:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
   repositories {
       maven {
           url "http://nexus.huya.com:8081/repository/maven-public"
           allowInsecureProtocol = true
       }
       google()
       mavenCentral()
   }
   dependencies {
       classpath 'com.android.tools.build:gradle:4.1.2'
       classpath 'com.github.kezong:fat-aar:1.3.6'
   }
}

task clean(type: Delete) {
   delete rootProject.buildDir
}

allprojects {
   repositories {
       maven {
           url "http://nexus.huya.com:8081/repository/maven-public"
           allowInsecureProtocol = true
       }
       maven {
           url "https://storage.googleapis.com/download.flutter.io"
       }
       google()
       mavenCentral()

   }
}

模块fluttercore的build.gradle主要处理aar的合并

plugins {
   id 'com.android.library'
}

apply plugin: 'com.kezong.fat-aar'

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
   localPropertiesFile.withReader('UTF-8') { reader ->
       localProperties.load(reader)
   }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
   throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

android {
   compileSdkVersion 31

   defaultConfig {
       minSdkVersion 22
       targetSdkVersion 31
       versionCode 1
       versionName "1.0"
       consumerProguardFiles "consumer-rules.pro"
   }

   buildTypes {
       release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
       }
   }
   compileOptions {
       sourceCompatibility JavaVersion.VERSION_1_8
       targetCompatibility JavaVersion.VERSION_1_8
   }

   repositories {
       flatDir {
           dirs 'libs'
       }
   }

   ndkVersion '21.0.6113669'
}

def engineVersion = file("${flutterRoot}/bin/internal/engine.version").text.trim()
println "----->flutter enginversion = ${engineVersion}"

dependencies {
   embed (name:"flutter_release-1.0.1" , ext:"aar")
   embed "io.flutter:flutter_embedding_release:1.0.0-${engineVersion}"
   embed "io.flutter:armeabi_v7a_release:1.0.0-${engineVersion}"
   embed "io.flutter:arm64_v8a_release:1.0.0-${engineVersion}"
}

apply from : "../publish.gradle"

四.构建聚合的aar

在fluttercoreWraaper根目录下执行

./gradlew :fluttercore:assembleRelease

得到的聚合aar,可以直接被其它native工程依赖,它的目录结果如下: multi_aar

五.flutter构建流程分析

后补.

六.flutter 源码编译

gityuan.com/2019/08/03/…

七.问题列表:

  • Error while initializing the Dart VM: Wrong full snapshot version, expected 'f2ed175878eb1ab377414135b301edb8' found 'c6f170657f1361110e2aed121c627869'

解决方法:

flutter channel dev
flutter upgrade
  • libflutter.so , flutter_embedding_xxx.jar本地路径在哪里?

这几个文件都是通过依赖加入进来的,本身是从远程maven仓库中下载,后面的版本号就是本地的flutter的engineversion,它的位置在fluttersdk目录下的${flutterRoot}/bin/internal/engine.version文件中.

  • 依赖完后dart代码怎么修改?

dart代码默认会包含在flutter的模块工程中,被打包成libapp.so了,目前只能是修改了dart重新打包成aar

  • 为什么打出来的aar中没有包含libflutter.so , flutter_embedding_xxx.jar?

这两个文件(实际上是多个,libflutter.so根据eabi的种类可能有多个)在flutter build aar过程中默认不会打到aar中,需要通过fat aar打包进去