Flutter Gradle构建失败:':flutter_tflite'未指定Namespace
构建Flutter项目时编译失败:flutter_tflite模块未指定Namespace
错误信息
FAILURE: Build failed with an exception. * What went wrong: A problem occurred configuring project ':flutter_tflite'. > Could not create an instance of type com.android.build.api.variant.impl.LibraryVariantBuilderImpl. > Namespace not specified. Specify a namespace in the module's build file. See https://d.android.com/r/tools/upgrade-assistant/set-namespace for information about setting the namespace. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
环境详情
Flutter version: 3.27.0 Dart version: 3.6.0 Android Studio version: 2024.2 (Artic Fox) Gradle version: 8.3 Java version: OpenJDK 21
项目配置文件
app/build.gradle
plugins { id "com.android.application" id "kotlin-android" // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id "dev.flutter.flutter-gradle-plugin" } android { namespace = "com.example.ornek12flutter" compileSdkVersion 34 ndkVersion = "25.1.8937393" compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } aaptOptions { noCompress 'tflite' noCompress 'lite' } kotlinOptions { jvmTarget = 17 } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId = "com.example.ornek12flutter" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. minSdkVersion 23 targetSdkVersion 34 versionCode = flutter.versionCode versionName = flutter.versionName } 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 = "../.." }
根目录build.gradle
buildscript { ext.kotlin_version = '1.7.20' repositories{ google() mavenCentral() } dependencies{ classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = "../build" subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(":app") } tasks.register("clean", Delete) { delete rootProject.buildDir }
app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application android:label="ornek12flutter" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:taskAffinity="" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> <meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <meta-data android:name="flutterEmbedding" android:value="2" /> </application> <uses-permission android:name="android.permission.CAMERA"/> <!-- Required to query activities that can process text, see: https://developer.android.com/training/package-visibility and https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT. In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. --> <queries> <intent> <action android:name="android.intent.action.PROCESS_TEXT"/> <data android:mimeType="text/plain"/> </intent> </queries> </manifest>
android/gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
settings.gradle
pluginManagement { def flutterSdkPath = { def properties = new Properties() file("local.properties").withInputStream { properties.load(it) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" return flutterSdkPath }() includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") repositories { google() mavenCentral() gradlePluginPortal() } } plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "8.3.2" apply false id "org.jetbrains.kotlin.android" version "2.0.20" apply false } include ":app"
依赖包
get: ^4.6.6 camera: ^0.11.0+2 permission_handler: ^11.3.1 flutter_tflite: ^1.0.1
核心代码
ScanController类
import 'dart:developer'; import 'package:camera/camera.dart'; import 'package:flutter_tflite/flutter_tflite.dart'; import 'package:get/get.dart'; import 'package:permission_handler/permission_handler.dart'; class ScanController extends GetxController{ late CameraController cameraController; late List<CameraDescription> cameras; @override void onInit() async{ super.onInit(); initCamera(); initTFLite(); } @override void dispose(){ super.dispose(); cameraController.dispose(); } var isCameraInitialized = false.obs; var cameraCount = 0; var x,y,w,h = 0.0; var label = ""; initCamera() async { if(await Permission.camera.request().isGranted){ cameras = await availableCameras(); cameraController = CameraController(cameras[0], ResolutionPreset.max, imageFormatGroup: ImageFormatGroup.yuv420); await cameraController.initialize().then((value){ cameraController.startImageStream((image) { cameraCount ++; if(cameraCount % 10 == 0){ cameraCount = 0; objectDetector(image); } update(); } ); }); isCameraInitialized(true); update(); }else{ print("Permission denied"); } } initTFLite() async { await Tflite.loadModel( model: "assets/detect.tflite", labels: "assets/label.txt", isAsset: true, numThreads: 1, useGpuDelegate: false, ); } objectDetector(CameraImage image) async { var detector = await Tflite.runModelOnFrame( bytesList: image.planes.map((e){ return e.bytes; }).toList(), asynch: true, imageHeight: image.height, imageWidth: image.width, imageMean: 127.5, imageStd: 127.5, rotation: 90, threshold: 0.4, ); if(detector != null){ var ourDetectedObject = detector.first; if(ourDetectedObject['confidenceInClass'] * 100 > 45){ label = detector.first['detectedClass'].toString(); h = ourDetectedObject['rect']['h']; w = ourDetectedObject['rect']['w']; x = ourDetectedObject['rect']['x']; y = ourDetectedObject['rect']['y']; } update(); } } }
CameraView组件
import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:ornek12flutter/scan.dart'; class CameraView extends StatelessWidget { const CameraView({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: GetBuilder<ScanController>( init: ScanController(), builder: (controller) { return controller.isCameraInitialized.value ? Stack( children: [ CameraPreview(controller.cameraController), Positioned( top: controller.y * 700, right: controller.x * 500, child: Container( width: controller.w * 100 * context.width / 100, height: controller.h * 100 * context.height / 100, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.green, width: 4.0), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( color: Colors.white, child: Text(controller.label), ), ], ), ), ), ], ) : const Center(child: Text("Loading Preview...")); }), ); } }
解决方案
方案1:替换为维护中的TFLite插件
flutter_tflite已停止维护,无法适配新版AGP的Namespace要求,推荐使用官方维护的tflite_flutter插件:
- 在
pubspec.yaml中移除flutter_tflite: ^1.0.1,添加以下依赖:
tflite_flutter: ^0.10.1 tflite_flutter_helper: ^0.4.0
- 调整代码适配新插件API:
- 模型加载改为使用
TfliteFlutter的Interpreter类 - 推理逻辑对应调整为新的方法调用
- 模型加载改为使用
方案2:手动修改flutter_tflite插件配置(临时修复)
找到本地pub缓存中的flutter_tflite插件目录(路径示例:~/.pub-cache/hosted/pub.dev/flutter_tflite-1.0.1/android),修改其build.gradle文件:
- 在
android代码块中添加Namespace配置:
android { namespace "com.gh.flutter_tflite" // 原有其他配置... }
- 确保插件的AGP版本与项目一致(比如将
com.android.tools.build:gradle版本改为7.1.2)
方案3:全局配置默认Namespace(不推荐)
在项目根目录的build.gradle中添加以下配置,为所有未指定Namespace的子项目自动设置:
subprojects { afterEvaluate { project -> if (project.hasProperty('android')) { project.android { if (!project.android.namespace) { namespace = "com.example.${project.name}" } } } } }
内容的提问来源于stack exchange,提问作者Smyy325
相关产品推荐
相关产品推荐

