首页 > 解决方案 > 使用 Android Studio 3.2 + Windows 编译 apk 失败

问题描述

最近我不得不切换到 Android Studio 3.2 Canary 以使用新的 AndroidX 组件。

我的主要开发环境是 Mac/OSX,一切正常。但是,本周我不得不切换到 Windows,并且在编译 apk 时出现以下异常。

当我使用 AndroidX 时,必须在 gradle.properties 文件中启用:

这是例外。

Caused by: com.android.builder.dexing.DexArchiveBuilderException: Failed to process C:\Users\rafael.chagas\.gradle\caches\transforms-1\files-1.1\jetified-play-services-basement-15.0.1.aar\a98f8e9d46ed106e8653ab19e7672193\jars\classes.jar
    at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.launchProcessing(DexArchiveBuilderTransform.java:877)
    at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.lambda$convertToDexArchive$7(DexArchiveBuilderTransform.java:802)
    at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: com.android.builder.dexing.DexArchiveBuilderException: Error while dexing.
    at com.android.builder.dexing.D8DexArchiveBuilder.getExceptionToRethrow(D8DexArchiveBuilder.java:124)
    at com.android.builder.dexing.D8DexArchiveBuilder.convert(D8DexArchiveBuilder.java:101)
    at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.launchProcessing(DexArchiveBuilderTransform.java:872)
    ... 6 more
Caused by: java.lang.NullPointerException: entry
    at java.util.zip.ZipFile.getInputStream(ZipFile.java:346)
    at com.android.tools.r8.ArchiveClassFileProvider.getProgramResource(ArchiveClassFileProvider.java:91)
    at com.android.builder.dexing.r8.CachingArchiveClassFileProvider.lambda$getProgramResource$0(CachingArchiveClassFileProvider.java:38)
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
    at com.android.builder.dexing.r8.CachingArchiveClassFileProvider.getProgramResource(CachingArchiveClassFileProvider.java:38)
    at com.android.builder.dexing.r8.ClassFileProviderFactory$OrderedClassFileResourceProvider.getProgramResource(ClassFileProviderFactory.java:78)
    at com.android.tools.r8.utils.ClassProvider$ClassFileResourceReader.collectClass(ClassProvider.java:97)
    at com.android.tools.r8.utils.ClassMap$ConcurrentClassLoader.get(ClassMap.java:241)
    at com.android.tools.r8.utils.ClassMap$ConcurrentClassLoader.get(ClassMap.java:217)
    at com.android.tools.r8.utils.ClassMap.get(ClassMap.java:115)
    at com.android.tools.r8.graph.LazyLoadedDexApplication.definitionFor(LazyLoadedDexApplication.java:47)
    at com.android.tools.r8.graph.AppInfo.definitionFor(AppInfo.java:62)
    at com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.findDefinitionFor(InterfaceMethodRewriter.java:255)
    at com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.rewriteMethodReferences(InterfaceMethodRewriter.java:140)
    at com.android.tools.r8.ir.conversion.IRConverter.rewriteCode(IRConverter.java:675)
    at com.android.tools.r8.ir.conversion.IRConverter.convertMethodToDex(IRConverter.java:346)
    at com.android.tools.r8.graph.DexClass.forEachMethodThrowing(DexClass.java:132)
    at com.android.tools.r8.ir.conversion.IRConverter.lambda$convertClassesToDex$2(IRConverter.java:332)
    at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:117)
    at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:38)
    at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:77)
    at com.google.common.util.concurrent.MoreExecutors$DirectExecutorService.execute(MoreExecutors.java:260)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:66)
    at com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:36)
    at com.android.tools.r8.ir.conversion.IRConverter.convertClassesToDex(IRConverter.java:330)
    at com.android.tools.r8.ir.conversion.IRConverter.convertToDex(IRConverter.java:245)
    at com.android.tools.r8.D8.optimize(D8.java:202)
    at com.android.tools.r8.D8.run(D8.java:162)
    at com.android.tools.r8.D8.lambda$run$1(D8.java:92)
    at com.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:56)
    at com.android.tools.r8.utils.ExceptionUtils.withD8CompilationHandler(ExceptionUtils.java:41)
    at com.android.tools.r8.D8.run(D8.java:89)
    at com.android.builder.dexing.D8DexArchiveBuilder.convert(D8DexArchiveBuilder.java:99)

上面的目标 .jar 文件是随机的。任何项目库都可能失败。

我知道这是 Android Studio 的 Canary 版本,但让我感兴趣的是这只发生在 Windows 操作系统上。在 Linux、OSX 中测试,完全没有问题。

谢谢!

标签: androidandroid-studio

解决方案


最后我找到了根本原因并解决了这个问题。

查看错误消息,导致异常的 Android R8 类是: src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java

深入研究 R8 源代码,我发现了最新的日志和一个全新的提交,它在读取 .zip 文件时更改了编码:

https://r8.googlesource.com/r8/+/a26659a1d07b4dc4ad0c3f8dbafd47d49efbc438

此提交更改了 R8 使用 UTF-8 编码读取 zip 存档的方式,并避免使用平台编码。这就是为什么只有 Windows 失败了。

我使用该提交测试了最新的 R8 版本,它成功了!只需将这些 (+) 行添加到您的项目build.gradle文件中。

 repositories {
     google()
     jcenter()
+    maven {
+        url "http://storage.googleapis.com/r8-releases/raw"
+    }
 }
dependencies {
+    classpath 'com.android.tools:r8:1.2.28'
     classpath 'com.android.tools.build:gradle:3.2.0-alpha18'
     classpath 'com.google.gms:google-services:4.0.0'
 }

“com.android.tools:r8:1.2.28”必须是依赖项中的第一个。

根据BUG 109992855,新版R8将在两周左右推送到Android Studio 3.2。同时,您必须使用上述修复。

希望对偶然发现此错误的任何人有所帮助。


推荐阅读