flutter-android混合编译,原生接入

关于作者: CSDN内容合伙人、技术专家, 从零开始做日活千万级APP ,带领团队单日营收超千万。

专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业化变现、人工智能等,希望大家多多支持。

目录

一、导读

我们继续总结学习flutter基础知识,温故知新。

二、概览

本文主要讲解原生Android工程接入Flutter ,进行混合编程。

首先,需要开发者按照原生Android、iOS的搭建流程搭建好开发环境。

然后,去Flutter官网下载最新的SDK,下载完毕后解压到自定义目录即可。

下载完后,还需要配置好环境,具体可参考 上一篇的 flutter配置的文章。

我们讲解一下三种方式;

Flutter 可以作为源代码 Gradle 子项目或 AAR 嵌入到现有的 Android 应用程序中。

集成流程可以使用带有Flutter 插件的Android Studio IDE或手动完成。

现有的 Android 应用可能支持mips或 等架构x86。Flutter 目前仅支持x86_64为、armeabi-v7a和构建预先 (AOT) 编译库arm64-v8a。

考虑使用abiFiltersAndroid Gradle 插件 API 来限制 APK 中支持的架构。这样做可以避免缺失libflutter.so运行时崩溃,例如:

groovy 复制代码
android {
    // ...
    defaultConfig {
        ndk {
            // Filter for architectures supported by Flutter
            abiFilters "armeabi-v7a", "arm64-v8a", "x86_64"
        }
    }
}

三、以原生module依赖

创建flutter module,然后以原生module那样依赖

自行参考
参考文档
参考文档

四、以aar方式依赖一

另一种方式是将flutter module打包成aar,然后在原生工程中依赖aar包,官方推荐aar的方式接入。

参考文档
参考文档

创建一个flutter module,然后打包成aar,这个过程就省略一下。

在 /flutter_module/.android/Flutter/build/outputs 目录下生成对应的aar包。

groovy 复制代码
stuff@ddddeMacBook-Pro loktar % flutter build aar

Running Gradle task 'assembleAarDebug'...                           7.1s
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarProfile'...                      1,714ms
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarRelease'...                      1,642ms
✓ Built build/host/outputs/repo

Consuming the Module
  1. Open <host>/app/build.gradle
  2. Ensure you have the repositories configured, otherwise add them:

      String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"
      repositories {
        maven {
            // 本地仓库,也是创建的 flutter工程目录, 也可以是自己创建的一个目录,然后把编译后的产物拷贝过来
            url '/Users/stuff/dddd/working/flutter_pro/loktar/build/host/outputs/repo'
        }
        maven {
            url "$storageUrl/download.flutter.io"
        }
      }

  3. Make the host app depend on the Flutter module:

    dependencies {
      debugImplementation 'com.ddd:flutter_debug:1.0'
      profileImplementation 'com.ddd:flutter_profile:1.0'
      releaseImplementation 'com.ddd:flutter_release:1.0'
    }


  4. Add the `profile` build type:

    android {
      buildTypes {
        profile {
          initWith debug
        }
      }
    }

To learn more, visit https://flutter.dev/go/build-aar

接下来,就是在原生Android工程中集成aar即可。

第一,在build.gradle中添加如下配置。

groovy 复制代码
android {
    ...
 
buildTypes {
        profile {
          initWith debug
        }
      } 
 
    String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?:
      "https://storage.googleapis.com"
      repositories {
        maven {
            // 本地仓库,也即是创建的 flutter工程目录
            url '/Users/mac/Flutter/module_flutter/build/host/outputs/repo'
        }
        maven {
            url "$storageUrl/download.flutter.io"
        }
      }
}

repositories {
    flatDir {
        dirs 'libs'
    }
}
dependencies {
      debugImplementation 'com.ddd.module_flutter:flutter_debug:1.0'
      profileImplementation 'com.ddd.module_flutter:flutter_profile:1.0'
      releaseImplementation 'com.ddd.module_flutter:flutter_release:1.0'
    }

第二、在AndroidManifest.xml中注册FlutterActivity实现

xml 复制代码
        <activity
            android:name="io.flutter.embedding.android.FlutterActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:theme="@style/AppTheme"
            android:windowSoftInputMode="adjustResize" />
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />

第三、启动FlutterActivity

java 复制代码
context.startActivity(FlutterActivity.withNewEngine().build(context));

// 
Intent intent = FlutterActivity.withCachedEngine(FlutterHelper.FLUTTER_ENGINE).build(context);
//重新设置一下目标class到子类BridgeActivity.class
intent.setClass(context, FlutterActivity.class);
context.startActivity(intent);

五、以aar方式依赖二

将flutter module打包成aar,然后在原生工程中依赖aar包, 但这种方式跟前一种有少许区别。

在新建的flutter工程中,可以看一下.android 目录下Flutter/build.gradle文件。

groovy 复制代码
apply plugin: "com.android.library"
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
想来,这就是flutter 相关的依赖,
我们在进入到目录下看看其他的gradle文件,发现有个依赖相关的文件,后面用到。

创建一个flutter module,然后打包成aar,这个过程就省略一下。

在 /flutter_module/.android/Flutter/build/outputs 目录下生成对应的aar包。

groovy 复制代码
stuff@ddddeMacBook-Pro loktar % flutter build aar

Running Gradle task 'assembleAarDebug'...                           7.1s
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarProfile'...                      1,714ms
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarRelease'...                      1,642ms
✓ Built build/host/outputs/repo

Consuming the Module
  1. Open <host>/app/build.gradle
  2. Ensure you have the repositories configured, otherwise add them:

      String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"
      repositories {
        maven {
            url '/Users/stuff/dddd/working/flutter_pro/loktar/build/host/outputs/repo'
        }
        maven {
            url "$storageUrl/download.flutter.io"
        }
      }

  3. Make the host app depend on the Flutter module:

    dependencies {
      debugImplementation 'com.ddd:flutter_debug:1.0'
      profileImplementation 'com.ddd:flutter_profile:1.0'
      releaseImplementation 'com.ddd:flutter_release:1.0'
    }


  4. Add the `profile` build type:

    android {
      buildTypes {
        profile {
          initWith debug
        }
      }
    }

To learn more, visit https://flutter.dev/go/build-aar

接下来,就是在原生Android工程中集成aar即可。

第一,在app的目录下新建libs文件夹,然后将生成aar包放入libs文件夹中

第二、新建一个flutter依赖文件

首先,在local.properties 目录新增flutter目录

groovy 复制代码
sdk.dir=/Users/sd/Library/Android/sdk
flutter.sdk=/Users/sd/development/flutter

然后在 "$flutter sdk目录/packages/flutter_tools/gradle/" 中找到resolve_dependencies.gradle文件,复制到app目录下。

然后进行修改如下:

groovy 复制代码
// This script is used to warm the Gradle cache by downloading the Flutter dependencies
// used during the build. This script is invoked when `flutter precache` is run.
//
// Command:
//  gradle -b <flutter-sdk>packages/flutter_tools/gradle/resolve_dependencies.gradle
//      resolveDependencies
//
// This way, Gradle can run with the `--offline` flag later on to eliminate any
// network request during the build process.
//
// This includes:
//   1. The embedding
//   2. libflutter.so

import java.nio.file.Paths


///add
//获取local.properties配置文件
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')

if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') {
        reader -> localProperties.load(reader)
    }
}

//获取flutter的sdk路径
def flutterRootPath = localProperties.getProperty('flutter.sdk')

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

 end


String storageUrl = System.getenv('FLUTTER_STORAGE_BASE_URL') ?: "https://storage.googleapis.com"

//File flutterRoot = projectDir.parentFile.parentFile.parentFile
File flutterRoot = new File(flutterRootPath)


String engineRealm = Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.realm")
        .toFile().text.trim()
if (engineRealm) {
    engineRealm = engineRealm + "/"
}

repositories {
    google()
    mavenCentral()
    maven {
        url "$storageUrl/${engineRealm}download.flutter.io"
    }
}


assert flutterRoot.isDirectory()
String engineVersion = Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.version")
        .toFile().text.trim()

System.out.println("hrl Resolving dependencies for Flutter $engineVersion")

configurations {
    flutterRelease.extendsFrom releaseImplementation
    flutterDebug.extendsFrom debugImplementation
    flutterProfile.extendsFrom debugImplementation
}

dependencies {
    flutterRelease "io.flutter:flutter_embedding_release:1.0.0-$engineVersion"
    flutterRelease "io.flutter:armeabi_v7a_release:1.0.0-$engineVersion"
    flutterRelease "io.flutter:arm64_v8a_release:1.0.0-$engineVersion"

    flutterProfile "io.flutter:flutter_embedding_profile:1.0.0-$engineVersion"
    flutterProfile "io.flutter:armeabi_v7a_profile:1.0.0-$engineVersion"
    flutterProfile "io.flutter:arm64_v8a_profile:1.0.0-$engineVersion"

    flutterDebug "io.flutter:flutter_embedding_debug:1.0.0-$engineVersion"
    flutterDebug "io.flutter:armeabi_v7a_debug:1.0.0-$engineVersion"
    flutterDebug "io.flutter:arm64_v8a_debug:1.0.0-$engineVersion"
    flutterDebug "io.flutter:x86_debug:1.0.0-$engineVersion"
    flutterDebug "io.flutter:x86_64_debug:1.0.0-$engineVersion"

//    compileOnly "io.flutter:flutter_embedding_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:armeabi_v7a_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:arm64_v8a_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:x86_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:x86_64_debug:1.0.0-$engineVersion"

    debugImplementation "io.flutter:flutter_embedding_debug:1.0.0-$engineVersion"
    debugImplementation "io.flutter:armeabi_v7a_debug:1.0.0-$engineVersion"
    debugImplementation "io.flutter:arm64_v8a_debug:1.0.0-$engineVersion"
    debugImplementation "io.flutter:x86_debug:1.0.0-$engineVersion"
    debugImplementation "io.flutter:x86_64_debug:1.0.0-$engineVersion"


    releaseImplementation "io.flutter:flutter_embedding_release:1.0.0-$engineVersion"
    releaseImplementation "io.flutter:armeabi_v7a_release:1.0.0-$engineVersion"
    releaseImplementation "io.flutter:arm64_v8a_release:1.0.0-$engineVersion"
}

第三、在build.gradle中添加如下配置。

groovy 复制代码
allprojects {
    repositories {

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

然后在app的build.gradle中添加如下配置。

groovy 复制代码
apply from: "${rootDir}/resolve_dependencies.gradle"

repositories {
    flatDir {
        dirs 'libs'
    }
}

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

    releaseImplementation(name:'flutter_release-1.0', ext:'aar')
    debugImplementation(name:'flutter_debug-1.0', ext:'aar')
}

第四、在AndroidManifest.xml中注册FlutterActivity实现

xml 复制代码
<activity
    android:name="io.flutter.embedding.android.FlutterActivity"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:theme="@style/AppTheme"
    android:windowSoftInputMode="adjustResize" />
<meta-data
    android:name="flutterEmbedding"
    android:value="2" />

第五、启动FlutterActivity

java 复制代码
context.startActivity(FlutterActivity.withNewEngine().build(context));

// 
Intent intent = FlutterActivity.withCachedEngine(FlutterHelper.FLUTTER_ENGINE).build(context);
//重新设置一下目标class到子类BridgeActivity.class
intent.setClass(context, FlutterActivity.class);
context.startActivity(intent);

如此即可

六、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

未经允许,不得转载。

相关推荐
忆江南9 小时前
iOS 深度解析
flutter·ios
明君8799710 小时前
Flutter 实现 AI 聊天页面 —— 记一次 Markdown 数学公式显示的踩坑之旅
前端·flutter
恋猫de小郭11 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
MakeZero13 小时前
Flutter那些事-交互式组件
flutter
shankss13 小时前
pull_to_refresh_simple
flutter
shankss13 小时前
Flutter 下拉刷新库新特性:智能预加载 (enableSmartPreload) 详解
flutter
阿巴斯甜16 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker16 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952717 小时前
Andorid Google 登录接入文档
android
黄林晴19 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack