Flutter兼容性问题:Namespace not specified
项目背景
部们有一个原生项目和一个Flutter项目,现在要把Flutter项目融入到原生项目,因此技术架构采用的是原生+Flutter混合开发模式。Flutter项目依赖了是flutter_boost第三方插件,结果编译报错:
FAILURE: Build failed with an exception.* What went wrong:
Could not determine the dependencies of task ':app:compileOverSeasAllAbiDebugJavaWithJavac'.
> Could not resolve all dependencies for configuration ':app:overSeasAllAbiDebugCompileClasspath'.> A problem occurred configuring project ':flutter_boost'.> 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: C:\Users\ws\AppData\Local\Pub\Cache\git\flutter_boost-6df80cc1ea425cde1bac7d0265407977221061df\android\build.gradle. See https://d.android.com/r/tools/upgrade-assistant/set-namespace for information about setting the namespace.If you've specified the package attribute in the source AndroidManifest.xml, you can use the AGP Upgrade Assistant to migrate to the namespace value in the build file. Refer to https://d.android.com/r/tools/upgrade-assistant/agp-upgrade-assistant for general information about using the AGP Upgrade Assistant.* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
AGP 8.0+ 要求所有模块必须在 build.gradle 明确声明 namespace,不再从 AndroidManifest.xml 的 package 属性自动推断。
解决方案
用一种能强制注入属性到子 module 的方式。
在 宿主工程(不是 Flutter module) 的build.gradle文件中加入以下代码:
allprojects {subprojects {afterEvaluate { project ->if (project.hasProperty('android')) {project.android {if (namespace == null) {namespace project.group}}}}}
}
最后看到的是:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {dependencies {classpath 'com.android.tools.build:gradle:8.12.0'}
}plugins {id 'com.android.application' version '8.10.0' apply falseid 'com.android.library' version '8.10.0' apply falseid 'org.jetbrains.kotlin.android' version '2.1.0' apply falseid "org.jetbrains.kotlin.kapt" version "2.1.0" apply falseid "com.google.gms.google-services" version '4.3.15' apply falseid "com.google.firebase.crashlytics" version '2.9.5' apply falseid "com.google.firebase.firebase-perf" version "1.4.2" apply falseid "io.github.JailedBird.ARouterPlugin" version('1.0.2') apply falseid "com.huawei.agconnect" version('1.9.1.301') apply false// id "com.alibaba" version('1.0.2') apply false
// id "com.sensorsdata.analytics.android" version '3.5.2' apply false
}// 解决gal插件报错:
// A problem occurred evaluating project ':gal'.
//> Could not get unknown property 'flutter' for extension 'android' of type com.android.build.gradle.LibraryExtension.
ext.flutter = [compileSdkVersion: 35,minSdkVersion : 24,targetSdkVersion : 35,ndkVersion : "27.0.12077973"]allprojects {subprojects {afterEvaluate { project ->if (project.hasProperty('android')) {project.android {if (namespace == null) {namespace project.group}}}}}
}apply from: 'config.gradle'subprojects {// 是否业务模块var isModuleProject = project.name.startsWith("module_") || project.name == "app" || project.name == "selector" || project.name.startsWith("pay_") || project.name.startsWith("push_")if (isModuleProject) {apply plugin: 'kotlin-kapt'}afterEvaluate {if (project.name == "OauthSDK" || project.name == "HeytapMsp") returnif (isModuleProject && project.name != "module_res") {dependencies {kapt 'com.alibaba:arouter-compiler:1.5.2'}println("projectName: ${project.name}")kapt {useBuildCache = falsearguments {println("projectName --> ${project.getName()}")arg("AROUTER_MODULE_NAME", project.getName())}}}dependencies {implementation 'androidx.core:core-ktx:1.7.0'implementation 'androidx.appcompat:appcompat:1.3.1'implementation 'com.google.android.material:material:1.9.0'testImplementation 'junit:junit:4.13.2'androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.3'androidTestImplementation 'androidx.test.ext:junit:1.1.3'androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'// 网络数据抓包.调试包也提供给测试看网络请求if (rootProject.ext.isOfficialRelease) {implementation "com.github.chuckerteam.chucker:library-no-op:3.5.2"} else {implementation "com.github.chuckerteam.chucker:library:3.5.2"}}android {compileSdk rootProject.ext.compileSdkdefaultConfig {minSdk rootProject.ext.minSdktargetSdk rootProject.ext.targetSdkbuildConfigField "Boolean", "isOverSeas", "${rootProject.ext.isOverSeas}"buildConfigField "String", "sensorProductId", "\"${rootProject.ext.sensorProductId}\""testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}compileOptions {sourceCompatibility JavaVersion.VERSION_17targetCompatibility JavaVersion.VERSION_17}plugins.withId("org.jetbrains.kotlin.android") {println("jvmTarget ${project.name} is kotlin module")kotlinOptions {jvmTarget = '17'}}buildFeatures {viewBinding truedataBinding true}sourceSets {main {jniLibs.srcDirs += ['src/main/jniLibs', 'libs']if (isOverSeas) {java.srcDirs 'src/main/java', 'src/overSeas/java'res.srcDirs 'src/main/res', 'src/overSeas/res'
// manifest.srcFile 'src/overSeas/AndroidManifest.xml', 'src/main/AndroidManifest.xml'} else {java.srcDirs 'src/main/java', 'src/internal/java'res.srcDirs 'src/main/res', 'src/internal/res'
// manifest.srcFile 'src/internal/AndroidManifest.xml', 'src/main/AndroidManifest.xml'}}}flavorDimensions "channel", "abi"productFlavors {if (isOverSeas) {//国外版本overSeas {dimension "channel"buildConfigField "String", "CHANNEL", "\"google\""}xiaomi {dimension "channel"buildConfigField "String", "CHANNEL", "\"xiaomi\""}
// huawei {
// dimension "channel"
// buildConfigField "String", "CHANNEL", "\"huawei\""
// }} else {//国内版本internal {dimension "channel"buildConfigField "String", "CHANNEL", "\"official\""}huawei {dimension "channel"buildConfigField "String", "CHANNEL", "\"huawei\""}xiaomi {dimension "channel"buildConfigField "String", "CHANNEL", "\"xiaomi\""}oppo {dimension "channel"buildConfigField "String", "CHANNEL", "\"oppo\""}vivo {dimension "channel"buildConfigField "String", "CHANNEL", "\"vivo\""}tencent {dimension "channel"buildConfigField "String", "CHANNEL", "\"tencent\""}honor {dimension "channel"buildConfigField "String", "CHANNEL", "\"honor\""}}// 32位+64位allAbi {dimension "abi"ndk {abiFilters "armeabi-v7a", "arm64-v8a"}}// 64位only64Abi {dimension "abi"ndk {abiFilters "arm64-v8a"}}}}}
}task clean(type: Delete) {delete rootProject.buildDir
}
感谢大家的支持,如有错误请指正,如需转载请标明原文出处!
