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

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插件:

  1. 在pubspec.yaml中移除flutter_tflite: ^1.0.1,添加以下依赖:
tflite_flutter: ^0.10.1
tflite_flutter_helper: ^0.4.0
  1. 调整代码适配新插件API:
    • 模型加载改为使用TfliteFlutter的Interpreter类
    • 推理逻辑对应调整为新的方法调用

方案2:手动修改flutter_tflite插件配置(临时修复)

找到本地pub缓存中的flutter_tflite插件目录(路径示例:~/.pub-cache/hosted/pub.dev/flutter_tflite-1.0.1/android),修改其build.gradle文件:

  1. 在android代码块中添加Namespace配置:
android {
    namespace "com.gh.flutter_tflite"
    // 原有其他配置...
}
  1. 确保插件的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:29:51