【发布时间】:2022-02-16 14:49:31
【问题描述】:
我正在使用 Android 的动态交付来实现我的一项功能。我已经分离了该功能的代码。我也在我的项目中使用导航组件。
我可以看到正在从进度条下载动态功能,下载后我正在使用导航组件导航到 Fragment2。
但是,当我尝试从“应用程序”中的 Fragment1 导航到“动态功能”中的 Fragment2 时,我遇到了异常。
Fatal Exception: android.content.res.Resources$NotFoundException: com.sample.sample.debug.dynamicfeature:navigation/dynamic_feature_nav
at androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.replaceWithIncludedNav(DynamicIncludeGraphNavigator.kt:95)
at androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.navigate(DynamicIncludeGraphNavigator.kt:79)
at androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.navigate(DynamicIncludeGraphNavigator.kt:40)
at androidx.navigation.NavController.navigate(NavController.java:1049)
at androidx.navigation.NavController.navigate(NavController.java:935)
at androidx.navigation.NavController.navigate(NavController.java:868)
at androidx.navigation.NavController.navigate(NavController.java:854)
at androidx.navigation.NavController.navigate(NavController.java:1107)
at com.compass.corelibrary.extensions.NavControllerExtensionsKt.navigateSafeSource(NavControllerExtensions.kt:18)
我的app的build.gradle文件是这样的
apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.heapanalytics.android'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.compass.jacoco.jacoco-android'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'jacoco'
apply plugin: 'kotlinx-serialization'
ext.versionMajor = 2
ext.versionMinor = 35
ext.versionPatch = 0
ext.minimumSdkVersion = 21
android {
compileSdkVersion 31
defaultConfig {
applicationId "com.sample.sample"
minSdkVersion project.ext.minimumSdkVersion
targetSdkVersion 31
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION_NAME
testInstrumentationRunner "com.sample.SampleAndroidJUnitRunner"
ext {
heapEnabled = true
heapAutoInit = true
heapEnvId = HEAP_KEY_GAMMA
}
}
signingConfigs {
beta {
keyAlias "circleci-beta-key-alias"
keyPassword "password"
storeFile file("circleci-beta-key.keystore")
storePassword "password"
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude 'META-INF/kotlinx-coroutines-core.kotlin_module'
exclude 'META-INF/kotlinx-serialization-runtime.kotlin_module'
}
flavorDimensions "version"
productFlavors {
debugFlavor {
getIsDefault().set(true)
dimension "version"
applicationIdSuffix ".debug"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "@string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "@string/fb_login_protocol_scheme_staging",
facebookAppId: "@string/facebook_app_id_staging",
facebookProvider: "@string/facebook_provider_staging"
]
}
alphaFlavor {
dimension "version"
applicationIdSuffix ".alpha"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "@string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "@string/fb_login_protocol_scheme_staging",
facebookAppId: "@string/facebook_app_id_staging",
facebookProvider: "@string/facebook_provider_staging"
]
}
betaFlavor {
dimension "version"
applicationIdSuffix ".beta"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "@string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "@string/fb_login_protocol_scheme_staging",
facebookAppId: "@string/facebook_app_id_staging",
facebookProvider: "@string/facebook_provider_staging"
]
}
rcFlavor {
dimension "version"
applicationIdSuffix ".rc"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "@string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "@string/fb_login_protocol_scheme_staging",
facebookAppId: "@string/facebook_app_id_staging",
facebookProvider: "@string/facebook_provider_staging"
]
}
playStoreFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "@string/com_auth0_domain_prod",
auth0Scheme: "compass",
facebookLoginProtocolScheme: "@string/fb_login_protocol_scheme_prod",
facebookAppId: "@string/facebook_app_id_prod",
facebookProvider: "@string/facebook_provider_prod"
]
ext.heapEnvId = HEAP_KEY_PRODUCTION
}
}
buildTypes {
debug {
getIsDefault().set(true)
debuggable true
multiDexEnabled true
signingConfig signingConfigs.beta
matchingFallbacks = ["release", "debug"]
buildConfigField "boolean", "ENABLE_LEAK_CANARY", enableLeakCanary
testCoverageEnabled false
FirebasePerformance {
instrumentationEnabled false
}
}
release {
minifyEnabled true
shrinkResources true
productFlavors.alphaFlavor.signingConfig signingConfigs.beta
productFlavors.betaFlavor.signingConfig signingConfigs.beta
productFlavors.rcFlavor.signingConfig signingConfigs.beta
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
matchingFallbacks = ["release", "debug"]
}
}
dexOptions {
javaMaxHeapSize "4g"
}
testOptions {
unitTests {
includeAndroidResources = true
// Added to ensure timezone is America/New_York for testing purposes
all{
jvmArgs '-Duser.timezone=America/New_York'
systemProperty 'robolectric.dependency.repo.url', 'https://repo1.maven.org/maven2'
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
androidTest { java.srcDirs = ['src/androidTest/kotlin'] }
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
buildFeatures {
viewBinding true
dataBinding true
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.0.5'
}
dynamicFeatures = [':dynamicfeature']
preBuild.dependsOn ktlintFormat
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//All the dependencies are here.
}
我的动态功能 build.gradle 看起来像
apply plugin: 'com.android.dynamic-feature'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'androidx.navigation.safeargs.kotlin'
android {
compileSdk 31
defaultConfig {
minSdk 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
getIsDefault().set(true)
debuggable true
matchingFallbacks = ["release", "debug"]
}
release {
matchingFallbacks = ["release", "debug"]
}
}
flavorDimensions "version"
productFlavors {
debugFlavor {
getIsDefault().set(true)
dimension "version"
matchingFallbacks = ["release", "debug"]
}
alphaFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
betaFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
rcFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
playStoreFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
}
buildFeatures {
viewBinding true
dataBinding true
}
}
dependencies {
implementation project(':app')
}
我正在从“app”中的 Fragment1 导航到“dynamicfeature”中的 Fragment2。 Fragment1 由“app”中的 MainActivity 托管。
我的应用导航图的条目为
<include-dynamic
android:id="@+id/me_dynamic_feature"
app:moduleName="dynamicfeature"
app:graphResName="dynamic_feature_nav"
app:graphPackage="${applicationId}.dynamicfeature" />
【问题讨论】:
-
那么它正在寻找的
com.sample.sample.debug.dynamicfeature:navigation/dynamic_feature_nav的哪一部分是错误的?是软件包名称还是您的功能模块中没有位于res/navigation/dynamic_feature_nav.xml的 XML 文件? -
@ianhanniballake - 我可以看到正在下载动态功能。下载后,我使用导航组件导航到 Fragment2。导航文件存在于动态功能导航文件夹中。在我的应用程序的 build.gradle 中,每种产品风味都有 applicationIdSuffix。应用程序 id 是 com.sample.sample 主应用程序的包名称是 com.sample.sample 动态功能模块的包名称是 com.sample.sample.dynamicfeature 我观察到的一件事是当我在 Activity 中托管 Fragment2 并尝试打开来自 Fragment1 的活动,然后一切正常。
-
如果
${applicationId}.dynamicfeature实际上不是您的动态功能模块的包名称,则似乎不适合放入其中。你试过在那里输入正确的包名吗? -
@ianhanniballake - 我试着把 app:graphPackage="com.sample.sample.dynamicfeature" 但它不工作。现在它甚至没有下载动态功能模块。我从这个答案中得到了将 applicationId 放入的想法 - stackoverflow.com/questions/64122383/…
标签: android dynamic-feature-module dynamic-feature android-app-bundle