0

我想将我们的 Android 应用程序资产提取到一个Android 资产包中,因为我们超过了 150 MB AAB(Android 应用程序包)的大小限制。在进行测试时,我遵循了Android App Bundle Test Instructions并将我的 Android Studio Run/Debug 配置从 app bundle 更改为 APK。执行此更改后,我可以在运行时从资产包中找到资产,同时调试我的应用程序。

但是,后来在运行时,我意识到 JDK11 方法Optional.isEmpty不再像以前使用 Run/Debug 配置Default APK时那样向后移植。这是它之前脱糖的方式。

 C$r8$backportedMethods$utility$Optional$0$isEmpty.isEmpty(someVariable)

经过一些 Google 研究后,我将Desugaring 库合并到我的项目中,这实际上解决了这个反向移植问题。但是,当继续时,我意识到作为依赖项拉入 Android 应用程序的库的某些部分正在使用以下方法。

public static ConcurrentHashMap.KeySetView newKeySet()

根据this stackoverflow article,这是一个导致以下异常的已知问题。

Process: com.test.android_application, PID: 20849
    java.lang.NoSuchMethodError: No static method newKeySet()Lj$/util/concurrent/ConcurrentHashMap$KeySetView; in class Lj$/util/concurrent/ConcurrentHashMap; or its super classes (declaration of 'j$.util.concurrent.ConcurrentHashMap')

这是我的 build.gradle 文件:

apply plugin: 'com.android.application'
android {
    compileSdkVersion 30
    defaultConfig {
        applicationId "com.myAndroidApp"
        minSdkVersion 21
        targetSdkVersion 30
        versionName "MyApplication"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testOptions {
            execution 'ANDROIDX_TEST_ORCHESTRATOR'
        }
        ndk {
            abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"
        }
    }

    signingConfigs {
        debug {
            storeFile file('debug_signing/debug.keystore')
            storePassword androidDebugStorePassword
            keyAlias 'androiddebugkey'
            keyPassword androidDebugKeyPassword
        }
        release {
            Properties releaseSigningProperties = new Properties()
            def releasePropsFile = file(releaseApiKeyFile)
            if (releasePropsFile.canRead()) {
                releaseSigningProperties.load(new FileInputStream(releasePropsFile))
                if (releaseSigningProperties != null) {
                    storeFile file(releaseStoreFile)
                    storePassword releaseSigningProperties['releaseStorePassword']
                    keyAlias releaseSigningProperties['releaseKeyAlias']
                    keyPassword releaseSigningProperties['releaseKeyPassword']
                }
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            multiDexKeepFile file('multidex-config.txt')
            signingConfig signingConfigs.release
        }
        debug{
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            multiDexKeepFile file('multidex-config.txt')
            signingConfig signingConfigs.debug
        }
    }

    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

}
dependencies {
    implementation group: 'com.myProject', name: 'internalDependency', version: '1.0'
    
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.cardview:cardview:1.0.0'

    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
    testImplementation 'junit:junit:4.13.1'
    testImplementation 'org.hamcrest:hamcrest-library:1.3'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    androidTestImplementation 'androidx.test:runner:1.4.0'
    androidTestImplementation 'androidx.test:core:1.4.0'
    androidTestUtil 'androidx.test:orchestrator:1.4.0'
    
    // Lifecycle components
    def archLifecycleVersion = '2.2.0'
    implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion
}

运行配置Default APK仅向后移植该Optional.isEmpty方法并保持public static ConcurrentHashMap.KeySetView newKeySet()不变(未对其执行脱糖操作)。这是我也想从 app bundle 为 APK实现的行为。

我显然可以重写被拉入 Android 应用程序的库中的这段代码,但问题仍然存在,Gradle 任务的区别是应用程序安装选项Default APKAPK from app bundle之间的区别。

我已经找到了这篇文章,但没有详细介绍。
此外,在构建应用程序时还会执行以下 Gradle 任务:

Default APK : assembleDebug  
APK from app bundle : extractApksForDebug
4

0 回答 0