首页/文章/flutter

flutter android端运行报错Namespace not specified. Specify a namespace in the module‘s build file

2024-11-06
1024 字约 4 分钟
...

在使用flutterSDK 3.24之后发现新建项目,项目默认都是基于AGP8了,由于 AGP 开始强制要求 namespace 配置,不仅仅是主工程,也包括第三方库都强制要求 namespace 。但是我们在引入第三方库的时候会发现部分库没能及时的去做相关配置,这也就导致了我们会出现标题错误:

出现这个问题,我们可能会通过去找到本地缓存的第三方库代码去修改它的build.gradle和AndroidManifest.xml来解决缺失 namespace 的报错问题,但是显然这种方式不太友好,毕竟正常项目可能会引用很多库,这个时候一个一个去修改太麻烦了。因此我们需要一种可以批量处理的方式,在编译的时候去做处理。

话不多说直接上代码吧,但还是建议连同下方补充的两项一起看完:

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

subprojects {
    afterEvaluate { project ->
        if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) {
            println "project: ${project.name} Namespace get: ${project.android.namespace}"
            def packageName = project.android.namespace ?: project.android.defaultConfig.applicationId ?: project.android.sourceSets.main.manifest.srcFile.text.find(/package="([^"]*)"/) ?: project.group
            project.android.namespace = packageName
            println "Namespace set to: ${packageName} for project: ${project.name}"
        }
    }
}

rootProject.buildDir = "../build"
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(":app")
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

通过在根目录下的build.gradle文件中添加以下代码就可以在编译的时候批量处理:

subprojects {
    afterEvaluate { project ->
        if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) {
            println "project: ${project.name} Namespace get: ${project.android.namespace}"
            def packageName = project.android.namespace ?: project.android.defaultConfig.applicationId ?: project.android.sourceSets.main.manifest.srcFile.text.find(/package="([^"]*)"/) ?: project.group
            project.android.namespace = packageName
            println "Namespace set to: ${packageName} for project: ${project.name}"
        }
    }
}

我让GPT写了一下代码解释,有兴趣的可以看一下:
以下是对这段代码的分析:

一、整体功能

这段 Groovy 代码主要是在 Gradle 项目中针对 Android 项目(包括 Android 库项目和应用项目)进行处理。具体功能包括获取项目的命名空间(package name),并在必要时进行设置。

二、代码结构及解释

1、afterEvaluate闭包:

在 Gradle 项目评估完成后执行的代码块。这意味着在项目的配置阶段结束后,这段代码才会被执行。

2、条件判断:

if (project.plugins.hasPlugin('com.android.library') ||project.plugins.hasPlugin('com.android.application')):检查项目是否应用了 Android 库插件或 Android 应用插件。只有满足这个条件的项目才会执行后续的代码。

3、获取和设置命名空间:

println "project: ${project.name} Namespace get: ${project.android.namespace}":打印当前项目的名称和已有的命名空间。
def packageName = project.android.namespace?: project.android.defaultConfig.applicationId?: project.android.sourceSets.main.manifest.srcFile.text.find(/package="([^"]*)"/)?: project.group:尝试从多个来源获取命名空间。如果项目已经设置了android.namespace,则使用该值;如果没有,尝试使用android.defaultConfig.applicationId;如果还没有,从 AndroidManifest.xml 文件中提取package属性的值;如果仍然没有找到,最后使用项目的group作为命名空间。
project.android.namespace = packageName:设置项目的命名空间为获取到的packageName。
println "Namespace set to: ${packageName} for project: ${project.name}":打印设置后的命名空间和项目名称。

最后我们再运行一下看看吧!

OK,成功运行!

补充一:如果出现如下截图错误的话

就改成下面代码,用来清除AndroidManifest.xml中的package,

subprojects {
    afterEvaluate { project ->
        if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) {
            println "project: ${project.name} Namespace get: ${project.android.namespace}"
            def packageName = project.android.namespace ?: project.android.defaultConfig.applicationId ?: project.android.sourceSets.main.manifest.srcFile.text.find(/package="([^"]*)"/) ?: project.group
            project.android.namespace = packageName
            println "Namespace set to: ${packageName} for project: ${project.name}"
            def manifestFile = project.android.sourceSets.main.manifest.srcFile
            if (manifestFile.exists()) {
                def manifestText = manifestFile.text
                if (manifestText.contains('package=')) {
                    manifestText = manifestText.replaceAll(/package="[^"]*"/, "")
                    manifestFile.text = manifestText
                    println "Package attribute removed in AndroidManifest.xml for project: ${project.name}"
                } else {
                    println "No package attribute found in AndroidManifest.xml for project: ${project.name}"
                }
            } else {
                println "AndroidManifest.xml not found for project: ${project.name}"
            }
        }
    }
}

注意添加完之后,第一次运行可能会报错,这个具体原因不清楚,不过不用管,接着再运行一次就可以了

补充二:如果出现如下截图错误的话可以通过配置gradle.properties文件添加这两行内容就可以了正常运行了。

android.nonTransitiveRClass=false
android.nonFinalResIds=false

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
flutter2026-10-14
Flutter Android 正式签名实战:生成密钥、配置构建与验证 APK
Flutter Android 正式签名实战:生成密钥、配置构建与验证 APK Android 正式签名不需要购买证书。开发者可以自己生成密钥,用它给 APK 签名;密钥的用途是建立稳定的应用身份。签名有效并不等于应用已经通过商店审核,也不等于应用功能已完成真机验收。 本文面向 Flutter Android 项目,介绍从开发签名切换到独立正式签名的完整流程。应用名称、目录、包名和证书信息均使用通用示例,不包含真实项目密码、私钥、签名指...
学习
flutter2026-10-14
Flutter 新版本发布实战:完整安装包与 Shorebird 热更新
一、先判断该发完整包还是补丁 | 这次改动 | 发布方式 | | | | | Dart 文案、Flutter 页面布局、业务逻辑修复 | 通常可以发布补丁 | | 纯 Dart 依赖变化 | 可以尝试补丁构建,仍需验证兼容性 | | Kotlin、Java、Swift、Objective C 或原生构建配置变化 | 发布完整包 | | 插件的原生实现变化、新增原生插件、权限变化 | 发布完整包 | | 新增或修改打包图片、字体、应用图标...
学习
flutter2026-07-01
Dart 入门回顾
1\. Dart 是什么 Dart 是一门类型安全、支持面向对象、支持异步编程的语言。它的语法和 JavaScript、TypeScript、Java、C# 都有一些相似之处。 Dart 常见使用场景: Flutter 跨平台应用开发 命令行工具 Web 应用 服务端接口或脚本 作为学习现代类型语言的入口 Dart 的几个核心特点: 静态类型:变量、函数返回值、参数都有类型。 类型推断:很多时候可以用 ,让 Dart 自动推断类型。 空...
学习
flutter2026-07-01
Flutter 常用 Widget 入门
Flutter 的核心思想是:一切皆 Widget。文字、图片、按钮、页面结构、布局、间距、滚动、动画、手势,几乎都由 Widget 组合出来。 1\. Widget 先分成几类理解 | 类别 | 常用 Widget | 解决什么问题 | | | | | | 应用入口 | 、 | 搭建应用外壳、主题、路由 | | 页面骨架 | 、 、 | 标准页面结构 | | 基础显示 | 、 、 | 显示文字、图标、图片 | | 布局容器 | 、 、...
学习
flutter2024-11-21
在 Flutter 中使用 webview_flutter 4.0
1. 2. ,已入选 3. 4. 本文是第 4 篇,定位是新手入门,介绍和演示 webview 的基础用法。最后还介绍了事件处理的技巧。因为是补写的,所以本来应该首发的却发在最后了。 环境准备已经在 说过了,不再赘述。既然是新手入门,就会本着详尽的原则,而且会多配示例。 获取页面信息 获取页面 title 核心方法:controller.getTitle 完整示例,放在 main.dart 就能运行。运行示例,点击获取 title 的按...
学习
flutter2024-11-03
Flutter中如何实现APP升级功能背景
背景 每个App应用中一定会包含的功能 ,App的运行平台不同实现升级功能的方式也就不同,基本分类如下所示。本文主要聚焦在使用Flutter框架开发的应用在安卓系统内如何更新,以及所涉及要点梳理。 IOS系统 Andriod系统 官网下载 各类应用市场 (本文聚焦点) 功能清单(按步骤) UpgradeCard组件(展示升级内容) 进行新旧版本对比判断是否需要更新 下载更新然后安装应用 UpgradeCard组件 组件需要包含基本标题、...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录