Android Studio 和 Android Gradle 插件的已知问题

本页记录了 Android Studio 3.5 和 Android Gradle 插件 3.5.0 的已知问题。如果您遇到本页尚未提及的问题,请报告错误

升级到预览版:每个版本的 Android Studio 和 Android Gradle 插件都旨在提高稳定性和性能以及增加一些新功能。要立即体验即将推出的版本的优势,请下载并安装 Android Studio 预览版

Android Studio 的已知问题

本节介绍了最新的稳定版 Android Studio 中存在的已知问题。

代码编辑

本部分说明了与代码编辑器相关的已知问题。

键盘输入冻结 - Linux 上的“iBus”问题

Linux 上的 iBus 守护进程与 Android Studio 之间存在一些已知的互动问题。在某些情况下,IDE 会停止响应键盘输入或开始输入随机字符。此错误由 iBus 和 XLib + AWT 之间的同步不完整而引发,并且已报告给上游的 JetBrainsiBus 开发者。此问题目前有三种解决方法:

  • 解决方法 1:强制 iBus 进入同步模式。在启动 Android Studio 之前,请在命令行中运行以下命令:
    $ IBUS_ENABLE_SYNC_MODE=1 ibus-daemon -xrd
  • 解决方法 2:在 Android Studio 中停用 iBus 输入方式。要仅为 Android Studio 停用 iBus 输入方式,请在命令行中运行以下命令:
    $ XMODIFIERS= ./bin/studio.sh
    这样做只会为 Android Studio 停用输入法,而不会影响您可能正在运行的任何其他应用。请注意,如果您在 Android Studio 处于运行状态时重启 iBus 守护进程(例如,通过运行 ibus-daemon -rd),则相当于为所有其他应用停用了输入法,并可能导致 Android Studio 的 JVM 崩溃并出现分段错误。
  • 解决方法 3:仔细检查快捷键设置,确保未将下一种输入法的快捷键设置为 Ctrl+Space,因为这也是 Android Studio 中的代码补全快捷键。Ubuntu 14.04 (Trusty) 中的默认快捷键是 Super+Space,但也可能沿用了先前版本的设置。要检查快捷键设置,请在命令行中运行 ibus-setup 以打开“IBus Preferences”窗口。在 Keyboard Shortcuts 下,选中 Next input method。如果它已被设为 Ctrl+Space,请将其更改为 Super+Space 或您所选的其他快捷键。

项目配置

本节说明与项目配置和 Gradle 同步相关的已知问题。

Gradle 同步失败:管道无效

问题在于,Gradle 守护进程会尝试使用 IPv4 而非 IPv6。

  • 解决方法 1:在 Linux 上,将以下内容放入 ~/.profile~/.bash_profile 中:
    export _JAVA_OPTIONS="-Djava.net.preferIPv6Addresses=true"
  • 解决方法 2:在 Android Studio 的 vmoptions 文件中,将 -Djava.net.preferIPv6Addresses=true 行更改为 -Djava.net.preferIPv6Addresses=true。要了解详情,请参阅网络 IPv6 用户指南

Gradle 同步或 SDK 管理器发生“peer not authenticated”错误

这些错误的根本原因在于 $JAVA_HOME/jre/lib/certificates/cacerts 中缺少证书。要解决此类错误,请按以下步骤操作:

  • 如果您使用了网络代理,请尝试直接连接。如果直接连接有效,那么为了通过代理进行连接,您可能需要使用 keytool 将代理服务器的证书添加到 cacerts 文件中。
  • 重新安装受支持且未经修改的 JDK。有一个会影响 Ubuntu 用户的已知问题会产生空的 /etc/ssl/certs/java/cacerts。要解决此问题,请在命令行中执行以下命令:
    sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure

部署

本节说明与将应用部署到已连接设备相关的已知问题。

macOS High Sierra 上的 Android 模拟器 HAXM

macOS High Sierra (10.13) 上的 Android 模拟器需要 HAXM 6.2.1+ 才能实现最佳的 macOS 兼容性和稳定性。不过,在 macOS 10.13 上安装 HAXM 等内核扩展的流程更为繁琐。您需要按以下方式手动允许安装内核扩展:

  1. 首先,尝试通过 SDK 管理器安装最新版本的 HAXM。
  2. 在 MacOS 中,依次转到 System Preferences > Security and Privacy
  3. 如果您看到“System software from developer "Intel Corporation Apps" was blocked from loading”,请点击 Allow

如需了解详情和解决方法,请参阅此 Apple 网页问题 62395878

应用更改

本部分说明与应用更改相关的已知问题。

Android Runtime 中的问题抛出错误

如果您使用的是搭载 Android 8.0 或 8.1 的设备,您在尝试应用某些类型的更改时(特别是当您使用 Kotlin 时),可能会看到“VERIFICATION_ERROR”消息。此消息是由 Android Runtime 相关问题引起的,在 Android 9.0 及更高版本中已解决这个问题。虽然该问题会导致“应用更改”失败,但您仍可以点击 Run 图标 Run 图标 重新运行您的应用来查看更改。但我们建议您将设备升级到 Android 9.0 或更高版本。

使用 android:sharedUserId 时无法应用更改

当您尝试更改尚未部署到正在运行的应用的类时,如果您的应用通过以下任一方式配置,“应用更改”将失败:

当“应用更改”因为这个问题而失败时,Android Studio 会显示以下消息:

Changes were not applied. JVMTI error: UNKNOWN_JVMTI_ERROR
    

要在 Android Studio 3.5 中解决此问题,请点击 Run 图标 Run 图标 以重新部署您的应用并查看相应更改。

调试和测试

本节说明与调试和测试应用相关的已知问题。

从 Android Studio 运行时,JUnit 测试在类路径中找不到资源

如果您的 Java 模块使用了特定的资源文件夹,那么从 IDE 运行测试时将找不到这些资源。您可以从命令行使用 Gradle 运行测试。也可以从 IDE 执行 Gradle check 任务。请参阅问题 64887 了解详情。

发生这个问题的原因是,从 IntelliJ 13 起,只能将一个文件夹用作类路径。IntelliJ 的编译工具会将所有资源复制到该编译文件夹中,但 Gradle 不会复制这些资源。

  • 解决方法 1:从 IDE 运行 Gradle check 任务,而不是运行单元测试。
  • 解决方法 2:更新编译脚本以手动将资源复制到编译文件夹中。如需了解详情,请参见此处的第 13 条评论

运行 JUnit 测试可能会编译两次代码

创建新项目时,系统可能会在 Make 和 Gradle-aware Make 这两个“发布前”步骤中创建模板 JUnit 配置。然后,系统会将此配置传播到所有已创建的 JUnit 运行配置。

  • 要为当前项目解决此问题,请依次点击 Run > Edit Configurations,然后将默认的 JUnit 配置更改为仅包含 Gradle-aware Make 步骤。
  • 要为今后的所有项目解决此问题,请依次点击 File > Close Project。您应该会看到欢迎屏幕。然后,依次点击 Configure > Project Defaults > Run Configurations,并将 JUnit 配置更改为仅包含 Gradle-aware Make 步骤。

某些测试运行配置无效

右键点击某个测试方法时,并非所有可用的运行配置都有效。具体而言,以下配置无效:

  • Gradle 运行配置(其图标为 Gradle 徽标)无效。
  • JUnit 运行配置(其图标不带绿色的 Android)不适用于插桩测试(此类测试无法在本地 JVM 上运行)。
Android Studio 还会记住在给定上下文中创建的运行配置(例如,右键点击特定类或方法),并且以后不会为您提供在其他配置中运行的选项。要解决此问题,请依次点击 Run > Edit Configurations,然后移除错误创建的配置。

调试原生代码时添加 Java 断点

当您的应用在原生代码中的断点处暂停时,Auto 和 Dual 调试程序可能无法立即识别您设置的新 Java 断点。要避免此问题,请在启动调试会话之前或在 Java 断点处暂停应用时添加 Java 断点。如需了解详情,请参阅问题 229949

退出原生调试程序

使用 Auto 或 Dual 调试程序调试 Java 和原生代码时,如果您通过 Java 代码逐步执行原生函数(例如,调试程序在调用原生函数的某行 Java 代码处暂停执行,并且您点击 Step Into 图标 )并且希望返回到 Java 代码,请点击 Resume Program 图标 (而非 Step Out 图标 或 Step Over 图标 )。您的应用进程仍将处于暂停状态,因此请点击 your-module-java 标签页中的 Resume Program 图标 来将其恢复。如需了解详情,请参阅问题 224385

分析器

本部分说明分析器的已知问题。

调试或剖析时出现 ADB 异常

使用 Platform Tools 29.0.3 时,原生调试和 Android Studio 分析器可能无法正常工作,当您依次选择 Help > Show Log 时,idea.log 文件中可能会显示“AdbCommandRejectedException”或“Failed to connect port”。将 Platform Tools 升级到 29.0.4 或更高版本可以解决这两个问题。

要升级 Platform Tools,请执行以下操作:

  1. 依次点击 Tools > SDK Manager 或点击工具栏中的 SDK Manager 图标 ,从 Android Studio 打开 SDK 管理器。
  2. 点击 Android SDK Platform-Tools 旁边的复选框,使其显示复选标记。左侧列中应会显示下载图标
  3. 点击 Apply 或 OK

Android Gradle 插件的已知问题

本节介绍了最新的稳定版 Android Gradle 插件中存在的已知问题。

对使用回车符 (CR) 命名的文件签名

JAR 签名(v1 方案)不支持包含回车符 (CR) 字符的文件名。(参阅问题 #63885809。)

API 变更

在 Android Gradle 插件 3.0.0 及更高版本引入的 API 变更中,部分功能被移除,因此您现有的编译可能会出现异常。插件的更高版本可能会引入新的公共 API 来替代失效的旧功能。

在编译时可能无法正常修改变体输出

新插件不支持使用 Variant API 来操纵变体输出,但仍然支持使用该 API 处理某些简单任务,例如在编译时更改 APK 名称,具体如下所示:

    // If you use each() to iterate through the variant objects,
    // you need to start using all(). That's because each() iterates
    // through only the objects that already exist during configuration time—
    // but those object don't exist at configuration time with the new model.
    // However, all() adapts to the new model by picking up object as they are
    // added during execution.
    android.applicationVariants.all { variant ->
        variant.outputs.all {
            outputFileName = "${variant.name}-${variant.versionName}.apk"
        }
    }
    

不过,涉及访问 outputFile 对象的复杂任务已不再受支持。这是因为在配置阶段不会再创建专门针对特定变体的任务。这导致插件不能预先了解所有的输出,但也缩短了配置时间。

manifestOutputFile 将不再可用

processManifest.manifestOutputFile() 方法不再可用,如果您调用该方法,会遇到以下错误:

    A problem occurred configuring project ':myapp'.
       Could not get unknown property 'manifestOutputFile' for task ':myapp:processDebugManifest'
       of type com.android.build.gradle.tasks.ProcessManifest.
    

您可以调用 processManifest.manifestOutputDirectory() 来返回包含所有已生成清单的目录的路径,而不是调用 manifestOutputFile() 来获取每个变体的清单文件。然后,您可以找到相应清单,并对该清单运用您的逻辑。以下示例将在清单中动态更改版本代码:

    android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
            output.processManifest.doLast {
                // Stores the path to the maifest.
                String manifestPath = "$manifestOutputDirectory/AndroidManifest.xml"
                // Stores the contents of the manifest.
                def manifestContent = file(manifestPath).getText()
                // Changes the version code in the stored text.
                manifestContent = manifestContent.replace('android:versionCode="1"',
                        String.format('android:versionCode="%s"', generatedCode))
                // Overwrites the manifest with the new text.
                file(manifestPath).write(manifestContent)
            }
        }
    }
    

修复的已知问题

本部分说明最新版本中已经修复的已知问题。如果您遇到所述的任何问题,请将 Android Studio 更新为最新稳定版或预览版

Android Studio 3.6 Beta 1 中修复的问题

  • LineageOS 上的 APK 安装错误:将应用部署到运行某些版本的 LineageOS 或 CyanogenMod 的设备可能会失败,并引发 INSTALL_PARSE_FAILED_NOT_APK 异常。

    在 Android Studio 3.6 Beta 1 及更高版本上,当您将应用部署到 LineageOS 或 CyanogenMod 设备时,IDE 通过执行完整的应用安装来处理此异常,这可能会导致部署时间变长。

Android Studio 3.5.2 中修复的问题

  • XML 代码样式损坏:在编辑 XML 代码时,如果从菜单栏中依次选择 Code > Reformat Code,IDE 会应用不正确的代码样式。

Android Studio 3.3.1 中修复的问题

  • 扫描基于 C++ 的项目时出现内存不足错误:如果 Gradle 扫描的项目在同一驱动器上的多个位置都有 C++ 代码,则扫描会涵盖这些位置的首个共通目录下的所有目录。扫描大量目录和文件可能会导致出现内存不足错误。

    要详细了解此问题,请参阅与该问题相关的错误