You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Android应用FFI自定义包架构路径匹配异常求助

问题描述

我们开发了一款使用自定义FFI包的Flutter应用,编译完成后,opencv_ffi库的结构如下:

opencv_ffi /
├─ x86_64
├─ x86
├─ armeabi_v7a
└─ arm64_v8a

生成的APK中lib目录结构与上述一致:

lib/
├─ x86_64
├─ x86
├─ armeabi_v7a
└─ arm64_v8a

但应用运行时,代码尝试加载lib/arm64路径,而非正确的lib/arm64_v8a路径。


相关配置文件

项目pubspec.yaml

name: opencv
description: A new Flutter opencv project.
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: '>=3.1.3 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  permission_handler: ^11.0.1
  cupertino_icons: ^1.0.2
  opencv_ffi:
    path: ./packages/opencv_ffi
  go_router: ^11.1.3
  camera: ^0.10.5+5
  path_provider: ^2.1.1
  syncfusion_flutter_sliders: ^23.1.40
  flutter_riverpod: ^2.4.3
  freezed_annotation: ^2.4.1
  camera_platform_interface: ^2.5.2
  path: ^1.8.3
  before_after: ^3.0.0+1
  syncfusion_flutter_charts: ^23.1.40
  image: ^4.1.3

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0
  build_runner: ^2.4.6
  freezed: ^2.4.3

flutter:
  uses-material-design: true

opencv_ffi包的pubspec.yaml

# The following section is specific to Flutter packages.
flutter:
  plugin:
    platforms:
      android:
        package: io.abdelrahman.opencv_ffi
        pluginClass: OpencvFfiPlugin
      ios:
        pluginClass: OpencvFfiPlugin

ffigen:
  output: "lib/opencv_ffi_bindings_generated.dart"
  name: "OpencvFfiBindings"
  headers:
    entry-points:
      - "src/processing/processing.h"

opencv_ffi包的AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.abdelrahman.opencv_ffi">
</manifest>

opencv_ffi包的build.gradle

group 'io.abdelrahman.opencv_ffi'
version '1.0'

buildscript {
    ext.kotlin_version = '1.8.21'
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.4.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

rootProject.allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
    if (project.android.hasProperty("namespace")) {
        namespace 'io.abdelrahman.opencv_ffi'
    }

    // Bumping the plugin compileSdkVersion requires all clients of this plugin
    // to bump the version in their app.
    compileSdkVersion 33

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
        main.jniLibs.srcDirs = ["libs"]
    }

    // // Bumping the plugin ndkVersion requires all clients of this plugin to bump
    // // the version in their app and to download a newer version of the NDK.
    // ndkVersion "23.1.7779620"

    // Invoke the shared CMake build with the Android Gradle Plugin.
    externalNativeBuild {
        cmake {
            path "../src/CMakeLists.txt"
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        minSdkVersion 21
        externalNativeBuild {
            cmake {
                // cppFlags '-frtti -fexceptions -std=c++2a'
                // arguments "-DANDROID_STL=c++_shared"
                cppFlags "-std=c++11 -fexceptions -frtti -stdlib=libc++ -v -g"

                arguments '-DBUILD_TESTING=OFF',
                        '-DANDROID_PLATFORM=android-21',
                        '-DANDROID_TOOLCHAIN=clang',
                        '-DCMAKE_VERBOSE_MAKEFILE=ON',
                        '-DANDROID_STL=c++_shared'
            }
        }
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }

}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

解决方案

1. 检查FFI加载代码的ABI名称映射

Flutter在Android上获取ABI时会返回标准名称arm64-v8a,如果你的代码中硬编码了arm64作为路径,就会导致加载错误。检查Dart加载逻辑,确保使用正确的ABI名称:

import 'dart:ffi';
import 'dart:io';
import 'package:path/path.dart' as path;

DynamicLibrary loadLibrary() {
  final String abi = Abi.current().name;
  // 确保ABI名称与实际目录完全匹配
  final String libraryPath = path.join(
    Directory.current.path,
    'opencv_ffi',
    abi,
    'libopencv_ffi.so', // 替换为你的实际库文件名
  );
  return DynamicLibrary.open(libraryPath);
}

2. 修正CMake输出目录配置

打开opencv_ffi包的src/CMakeLists.txt,添加或修改以下配置,确保编译后的库文件输出到正确的ABI目录:

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../libs/${ANDROID_ABI})

这会让CMake自动将库文件放到对应armeabi-v7a、arm64-v8a等目录下,避免目录名称不匹配。

3. 清理并重新构建项目

执行以下命令清理缓存,避免旧构建文件干扰:

flutter clean
flutter pub get
cd packages/opencv_ffi
./gradlew clean
cd ../..
flutter build apk

4. 验证APK结构

构建完成后解压APK,确认lib目录下的arm64-v8a目录存在且包含正确的.so文件,排除打包过程中的异常问题。

内容的提问来源于stack exchange,提问作者Jpicerno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:43:26