Как только я добавил в свое приложение модули динамических функций, я смог успешно провести рефакторинг первой функции (заказы), построить и развернуть. Но при рефакторинге второго модуля, то есть перемещении файлов и ресурсов в этот модуль, я получаю эту ошибку при сборке:
Execution failed for task ':features:catalog:createDebugCompatibleScreenManifests'.
> Failed to calculate the value of task ':features:catalog:createDebugCompatibleScreenManifests' property 'applicationId'.
> Failed to query the value of property 'testedApplicationId'.
> Collection has more than one element.
Я пробовал следующие исправления:
applicationId
)Любые указатели относительно того, что вызывает эту проблему сборки?
Дополнительная информация: я использую инъекцию зависимостей с koin.
Приложение/Основной модуль manifest.xml
<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools"
package = "com.example.app">
<uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
<uses-feature
android:name = "android.hardware.camera2"
android:required = "false" />
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
<application
android:name = ".ExampleApp"
android:allowBackup = "true"
android:icon = "@mipmap/ic_launcher"
android:networkSecurityConfig = "@xml/network_security_config"
android:roundIcon = "@mipmap/ic_launcher_round"
android:supportsRtl = "true"
android:theme = "@style/AppTheme"
tools:ignore = "AllowBackup,GoogleAppIndexingWarning">
<meta-data
android:name = "com.google.android.geo.API_KEY"
android:value = "@string/google_maps_key" />
<meta-data
android:name = "firebase_crashlytics_collection_enabled"
android:value = "${crashlyticsCollectionEnabled}" />
<activity android:name = "com.kyosk.app.ui.fragment.login.LoginActivity" />
<activity android:name = "com.kyosk.app.ui.activity.SplashActivity">
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name = "com.kyosk.app.ui.activity.Home" />
<service
android:name = ".service.MessagingService"
android:exported = "false">
<intent-filter>
<action android:name = "com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:name = ".location.services.LocationUpdatesService"
android:exported = "false" />
<service
android:name = ".location.services.MapsLocationUpdatesService"
android:exported = "false" />
<provider
android:name = "androidx.core.content.FileProvider"
android:authorities = "${applicationId}.fileprovider"
android:exported = "false"
android:grantUriPermissions = "true">
<meta-data
android:name = "android.support.FILE_PROVIDER_PATHS"
android:resource = "@xml/file_paths" />
</provider>
</application>
</manifest>
Приложение/Основной модуль build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'realm-android'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: (BuildPlugins.dependencyUpdateChecker)
android {
compileSdkVersion AndroidSDK.compileSDKVersion
buildToolsVersion Versions.buildTools
defaultConfig {
applicationId "com.example.app"
minSdkVersion AndroidSDK.minimumSDKVersion
targetSdkVersion AndroidSDK.targetSDKVersion
versionCode Versions.versionCode
versionName Versions.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
manifestPlaceholders = [crashlyticsCollectionEnabled: "false"]
applicationIdSuffix(".debug")
versionNameSuffix("-debug")
buildConfigField("String", "BASE_URL", debug_url)
}
staging {
initWith(release)
manifestPlaceholders = [crashlyticsCollectionEnabled: "false"]
applicationIdSuffix(".staging")
versionNameSuffix("-staging")
buildConfigField("String", "BASE_URL", staging_url)
}
release {
manifestPlaceholders = [crashlyticsCollectionEnabled: "true"]
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField("String", "BASE_URL", production_url)
}
}
buildFeatures {
viewBinding = true
dataBinding = true
}
kotlinOptions {
jvmTarget = '1.8'
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
kapt {
correctErrorTypes = true
}
dynamicFeatures = [':features:kiosks', ':features:catalog', ':features:checkout', ':features:summary', ':features:orders']
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation Libraries.kotlinStandardLibrary
implementation Libraries.appCompat
implementation Libraries.constraintLayout
api Libraries.materialComponents
implementation Libraries.navigationFragment
implementation Libraries.navigationUI
implementation Libraries.preferences
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
//firebase libs
implementation Libraries.firebaseMessaging
implementation Libraries.firebaseConfig
// Recommended: Add the Firebase SDK for Google Analytics.
implementation Libraries.firebaseAnalytics
implementation Libraries.firebaseCrashlytics
// DI
api Libraries.koinAndroid
api Libraries.koinLifecycle
api Libraries.koinViewmodel
//maps
implementation 'com.google.android.gms:play-services-maps:17.0.0'
//own modules
implementation project(path: ':location-services')
implementation project(path: ':network')
api project(path: ':helpers')
//glide
implementation 'com.github.bumptech.glide:glide:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
//loading button
api Libraries.buttonProgress
//pagination lib
implementation Libraries.jdroidCoder
//EventBus
api Libraries.eventBus
//logging
api Libraries.timber
//anko
api Libraries.ankoDesign
api Libraries.ankoCommons
//play core library
implementation(Libraries.playCore)
implementation(Libraries.playCorektx)
// paris for applying styles to views dynamically
implementation 'com.airbnb.android:paris:1.7.2'
// lottie for animations
implementation 'com.airbnb.android:lottie:3.5.0'
// Okhttp Profiler
implementation Libraries.loggingInterceptor
// Test libs
testImplementation(TestLibraries.junit4)
androidTestImplementation(TestLibraries.androidX)
androidTestImplementation(TestLibraries.espresso)
androidTestImplementation(TestLibraries.annotationLib)
}
Функциональный модуль 1 (заказы) manifest.xml
<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:dist = "http://schemas.android.com/apk/distribution"
package = "com.example.app.orders">
<dist:module
dist:instant = "false"
dist:title = "@string/title_orders">
<dist:delivery>
<dist:install-time />
</dist:delivery>
<dist:fusing dist:include = "true" />
</dist:module>
</manifest>
Особенность 1 (заказы) build.gradle
apply plugin: 'com.android.dynamic-feature'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: (BuildPlugins.dependencyUpdateChecker)
android {
compileSdkVersion AndroidSDK.compileSDKVersion
buildToolsVersion Versions.buildTools
defaultConfig {
applicationId "com.example.app.orders"
minSdkVersion AndroidSDK.minimumSDKVersion
targetSdkVersion AndroidSDK.targetSDKVersion
versionCode Versions.versionCode
versionName Versions.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {}
staging {}
release {}
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding = true
dataBinding = true
}
}
dependencies {
implementation project(":app")
implementation project(path: ':network')
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation Libraries.kotlinStandardLibrary
implementation Libraries.ktxCore
implementation Libraries.appCompat
implementation Libraries.constraintLayout
implementation Libraries.materialComponents
implementation Libraries.navigationFragment
implementation Libraries.navigationUI
implementation Libraries.buttonProgress
implementation Libraries.ankoDesign
implementation Libraries.ankoCommons
implementation(Libraries.coroutinesAndroid)
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
// Test libs
testImplementation(TestLibraries.junit4)
androidTestImplementation(TestLibraries.androidX)
androidTestImplementation(TestLibraries.espresso)
androidTestImplementation(TestLibraries.annotationLib)
}
Удалите приложение из эмулятора, а затем перезапустите его.
Проблема оказалась в библиотеке, которую я импортировал.
В библиотеке был плагин apply plugin: 'com.android.application'
вместо
apply plugin: 'com.android.library'
Таким образом, задача сборки gradle искала applicationId
и applicationName
в манифесте, которого там не было.
Упс, ошибка разработчика.
Для меня это произошло при добавлении нового динамического функционального модуля с несколькими вариантами.
Я решил это, изменив внутри module.gradle:
implementation project(path: ':app', configuration: 'default')
в
implementation project(":app")
Затем добавьте ароматизаторы в module.gradle.
flavorDimensions "app"
productFlavors {
flavor1 {}
flavor2 {}
flavor3 {}
}
Вот мой последний модуль.gradle
apply plugin: 'com.android.dynamic-feature'
android {
compileSdkVersion 29
buildToolsVersion '29.0.3'
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
flavorDimensions "app"
productFlavors {
flavor1 {}
flavor2 {}
flavor3 {}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation project(":app")
}
Привет! Попробуйте использовать эту строку «проект реализации («: приложение»)». Скажи мне, если тебе нужна дополнительная помощь!
@michgauz, у тебя такая же ошибка? Проверьте плагины, которые вы использовали в верхней части уровня модуля build.gradle, чтобы убедиться, что они: примените плагин: «com.android.application» для модуля приложения, примените плагин: «com.android.library» для модулей lib и «com.android.dynamic-feature» для динамических модулей
Спасибо за ваш ответ, но, наконец, моя проблема была немного другой 😅 stackoverflow.com/questions/67336240/…
@Alex, поскольку наш код из модуля приложения использует динамический модуль, мы должны иметь implementation project(path: ':dynamic-module')
в градиенте приложения. Если мы добавим implementation project(":app")
к градиенту модуля, это создаст ошибку циклической ссылки, не так ли?
@LêTháiPhúcQuang да, в app.gradle у вас должен быть проект реализации («: модуль»), но я говорил о внутренней части файла MODULE.GRADLE. Также у меня были проблемы при использовании более длинной версии (путь: «приложение») по сравнению с («: приложение»)
Я пробовал оба, но это не работает, если модуль приложения gradle объявляет зависимости от :module, кроме того, это нарушает точку динамической функции, не так ли?
в моем проекте единственная зависимость находится внутри module.gradle "implementation project(":app"), а не наоборот. Конечно, вы можете удалить все зависимости между модулями, если они вам не нужны
Привет! Я думаю, это то, что я ищу. Не могли бы вы объяснить немного больше, что вы сделали? Добавление «проекта реализации (путь: ': приложение', конфигурация: 'по умолчанию')» в динамическом модуле приводит к еще одной ошибке: «Коллекция пуста»... Спасибо