Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Android 스튜디오 및 Android Gradle 플러그인의 알려진 문제

이 페이지는 Android 스튜디오 및 Android Gradle 플러그인의 현재 알려진 문제를 추적합니다. 여기에 아직 포함되지 않은 문제를 신고하려면 버그 신고를 참조하세요.

Android 스튜디오의 알려진 문제

  • C++ 기반 프로젝트 검색 시 메모리 부족 오류: Gradle이 동일한 드라이브에서 둘 이상의 위치에 C ++ 코드가 있는 프로젝트를 검색하면 첫 번째 공통 디렉터리 아래의 모든 디렉터리가 검색에 포함됩니다. 많은 수의 디렉터리와 파일을 검색하면 메모리 부족 오류가 발생할 수 있습니다.

    프로젝트에서 이 동작이 발생하면 Android 스튜디오 3.2를 사용하는 것이 좋습니다. 이 문제에 관한 자세한 내용은 문제와 관련된 버그를 참조하세요.

  • Espresso Test Recorder 컴파일 실패: Espresso Test Recorder를 사용하는 프로젝트를 빌드하려고 하면 Execution failed for task ':app:compileDebugAndroidTestJavaWithJavac' 메시지와 함께 컴파일이 실패합니다. 이 문제는 버전 3.0.2 이상의 espresso-core 종속성을 사용하는 3.2 미만 버전의 Android 스튜디오에 영향을 줍니다. 이 문제는 Android 스튜디오 3.2 이상에는 영향을 주지 않습니다.

    Android 스튜디오 3.1 이하를 사용하는 경우 Espresso 설정 안내에 나오는 것처럼 버전 3.0.2 미만의 espresso-core 종속성을 설정하거나 별도의 rules 종속성을 추가하여 이 문제를 해결할 수 있습니다.

  • @RestrictTo Lint 검사가 Windows 시스템에서 작동하지 않음: Android 스튜디오 2.3에서는 @RestrictTo Lint 검사가 Windows 시스템에서 오류 메시지를 올바르게 트리거하지 않습니다.

  • 이름에 괄호가 포함된 가상 기기가 실행되지 않음: Android 스튜디오 버전 2.2에서는 가상 기기의 이름에 괄호를 포함할 수 있지만(실제로 Android TV와 같은 일부 기기의 이름에 괄호가 자동으로 포함되어 있음), 이름에 괄호가 사용된 가상 기기는 실행할 수 없습니다. 이 문제를 방지하려면 가상 기기를 편집하여 이름에서 '(' 및 ')' 문자를 모두 제거합니다.

    이 문제는 Android 스튜디오 2.3부터 해결되었습니다.

  • Instant Run이 Jack과 호환되지 않음: Instant Run은 현재 Jack 컴파일러와 호환되지 않으므로 Jack 컴파일러를 사용하는 프로젝트에 대해 사용 중지됩니다. (자바 8 언어 기능을 사용하는 경우에만 Jack 컴파일러를 사용해야 합니다.)

  • 앱의 클래스 파일이 필요한 도구 및 라이브러리가 Jack과 호환되지 않음: .class 파일(예: JaCoCo, Mockito 및 일부 Lint 검사)을 읽는 다양한 도구가 현재 Jack 컴파일러와 호환되지 않습니다.

  • Linux에서 프로젝트가 NTFS인 경우 Gradle 빌드에서 출력 폴더를 삭제할 수 없음: NTFS의 파일 잠금 동작으로 인해 Windows 시스템에서 Android 스튜디오는 색인화하기 전에 클래스의 JAR 파일을 다른 위치로 자동 복사하여 후속 Gradle 빌드가 빌드/트리를 삭제하고 변경할 수 있도록 합니다. 자세한 내용은 문제 202297을 참조하세요. Linux 또는 OSX 시스템에서 NTFS를 사용하는 경우에는 이 동작을 사용할 수 없지만, 다음 줄의 주석 처리를 제거하여 idea.properties 파일에 수동으로 지정할 수 있습니다.

    idea.jars.nocopy=false

  • Mac 성능: 스튜디오 2.2와 함께 번들로 제공되는 OpenJDK 1.8.0_76은 Mac에서 몇 가지 문제가 있습니다. 해상도가 조정된 외부 4K 모니터를 사용하면 문제 203412IDEA-144261에 설명된 것처럼 렌더링 성능에 부정적인 영향을 미쳐서 IDE가 응답하지 않을 수도 있습니다. 또한 문제 223749IDEA-158500에서 보고된 바와 같이 Mac 10.12(Sierra)에서 스크롤이 매우 민감합니다.

  • Gradle 동기화 실패: 파이프 단절: Gradle 데몬에서 IPv6 대신 IPv4를 사용하려고 하는 문제입니다.

    • 해결 방법 1: Linux에서 ~/.profile 또는 ~/.bash_profile에 다음을 삽입합니다.
      export _JAVA_OPTIONS="-Djava.net.preferIPv6Addresses=true"
    • 해결 방법 2: Android 스튜디오의 vmoptions 파일에서 줄 -Djava.net.preferIPv6Addresses=true-Djava.net.preferIPv6Addresses=true로 변경합니다. 자세한 내용은 네트워킹 IPv6 사용자 가이드를 참조하세요.
  • Gradle 동기화 또는 SDK Manager의 '피어가 인증되지 않음' 오류: 이러한 오류의 근본 원인은 $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
  • Android 스튜디오에서 JUnit을 실행하면 클래스 경로의 누락된 리소스를 테스트함: 자바 모듈에 특정 리소스 폴더가 있으면 IDE에서 테스트를 실행할 때 이러한 리소스가 발견되지 않습니다. 명령줄에서 Gradle을 사용하여 테스트를 실행하면 제대로 작동합니다. IDE에서 Gradle check 작업을 실행하는 것도 제대로 작동합니다. 자세한 내용은 문제 64887을 참조하세요.

    IntelliJ 13부터 클래스 경로로 하나의 폴더만 사용할 수 있기 때문에 이 문제가 발생합니다. IntelliJ의 빌더는 모든 리소스를 해당 빌드 폴더에 복사하지만, Gradle은 리소스를 복사하지 않습니다.

    • 해결 방법 1: 단위 테스트를 실행하는 대신 IDE에서 Gradle check 작업을 실행합니다.
    • 해결 방법 2: 빌드 스크립트를 업데이트하여 리소스를 빌드 폴더에 수동으로 복사합니다. 자세한 내용은 댓글 #13을 참조하세요.
  • JUnit 테스트를 실행하면 코드가 두 번 컴파일될 수 있음: 새로운 프로젝트를 생성하면 두 가지 '출시 전' 단계인 Make와 Gradle 인식 Make를 포함하는 템플릿 JUnit 구성이 생성될 수 있습니다. 그런 다음, 이 구성은 생성된 모든 JUnit 실행 구성으로 전파됩니다.

    • 현재 프로젝트에서 이 문제를 해결하려면 Run > Edit Configurations를 클릭하고 기본 JUnit 구성을 변경하여 Gradle 인식 Make 단계만 포함하도록 합니다.
    • 향후 프로젝트에서 이 문제를 해결하려면 File > Close Project를 클릭합니다. 그러면 환영 화면이 나타납니다. 다음으로, Configure > Project Defaults > Run Configurations를 클릭하고 JUnit 구성을 변경하여 Gradle 인식 Make 단계만 포함하도록 합니다.
  • 일부 테스트 실행 구성이 작동하지 않음: 테스트 메서드를 마우스 오른쪽 버튼으로 클릭할 때 사용 가능한 실행 구성이 모두 유효한 것은 아닙니다. 특히 다음 구성이 유효하지 않습니다.

    • Gradle 실행 구성(Gradle 로고 아이콘이 있음)은 작동하지 않습니다.
    • JUnit 실행 구성(초록색 Android가 없는 아이콘이 있음)은 로컬 JVM에서 실행할 수 없는 계측 테스트에 적용되지 않습니다.
    Android 스튜디오는 또한 주어진 컨텍스트(예: 특정 클래스 또는 메서드를 마우스 오른쪽 버튼으로 클릭)에서 생성된 실행 구성을 기억하여 향후에 다른 구성에서 실행하지 않도록 합니다. 이 문제를 해결하려면 Run > Edit Configurations를 클릭하고 잘못 생성된 구성을 삭제합니다.

  • Linux 및 Awesome WM 3.4: Android 스튜디오 버전 0.8.3 이상은 'Awesome WM' 창 관리자 버전 3.4에서 제대로 작동하지 않을 수 있습니다. 이 문제를 해결하려면 Awesome WM 버전 3.5로 업그레이드합니다.

  • 키보드 입력이 정지됨 - Linux의 'iBus' 문제 : Linux의 iBus 데몬과 Android 스튜디오 간에는 몇 가지 알려진 상호작용이 있습니다. 일부 시나리오에서는 IDE가 키보드 입력에 응답하지 않거나 임의의 문자를 입력하기 시작합니다. 이 버그는 iBus와 XLib + AWT 간의 일부 누락된 동기화로 인해 트리거되며 이미 JetBrainsiBus에 보고되었습니다. 현재 이 문제를 해결하는 세 가지 방법이 있습니다.

    • 해결 방법 1: iBus를 동기 모드로 강제 전환합니다. Android 스튜디오를 시작하기 전에 명령줄에서 다음을 실행합니다.
      $ IBUS_ENABLE_SYNC_MODE=1 ibus-daemon -xrd
    • 해결 방법 2: Android 스튜디오에서 iBus 입력을 사용 중지합니다. Android 스튜디오에서만 iBus 입력을 사용 중지하려면 명령줄에서 다음을 실행합니다.
      $ XMODIFIERS= ./bin/studio.sh
      이렇게 하면 실행 중인 다른 애플리케이션은 그대로 두고 Android 스튜디오의 입력 방법만 사용 중지됩니다. Android 스튜디오가 실행 중일 때 데몬을 다시 시작하면(예: ibus-daemon -rd를 실행) 다른 모든 애플리케이션의 입력 방법이 사용 중지되며 세그먼트 오류로 인해 Android 스튜디오의 JVM이 다운될 수도 있습니다.
    • 해결 방법 3: 단축키 바인딩을 다시 확인하여 Next input shortcut이 Control+Space로 설정되지 않았는지 확인합니다. 이 단축키는 Android 스튜디오에서 코드 작성 단축키입니다. Ubuntu 14.04(Trusty)에서는 Super+Space가 기본 단축키지만 이전 버전의 설정이 여전히 남아있을 수 있습니다. 단축키 바인딩을 확인하려면 명령줄에서 ibus-setup을 실행하여 IBus 환경설정 창을 엽니다. Keyboard Shortcuts 아래에서 Next input method를 확인합니다. Control+Space로 설정되어 있으면 Super+Space나 원하는 다른 단축키로 변경합니다.
  • Ubuntu 및 JAyatana: JAyatana를 사용하면 Java Swing 애플리케이션이 Ubuntu의 Unity 그래픽 셸에서 글로벌 메뉴와 통합될 수 있습니다. 경우에 따라 Android 스튜디오의 Unity에서 다음과 같은 오류 메시지와 함께 NullPointerException이 발생할 수 있습니다.

    java.lang.NullPointerException
        at com.jarego.jayatana.swing.SwingGlobalMenu.getSwingGlobalMenuWindowController(SwingGlobalMenu.java:204)
        at com.jarego.jayatana.swing.SwingGlobalMenu.installLockParentGlobalMenu(SwingGlobalMenu.java:160)
        at ...
    자세한 내용은 문제 187179를 참조하세요. 이 문제로 인해 최신 버전의 Ubuntu는 JAyatana를 기본적으로 사용 중지합니다. 이 문제가 발생하면 두 가지 가능한 해결 방법이 있습니다(자세한 내용은 이 Stack Overflow 포스트 참조).

    • 해결 방법 1: Android 스튜디오를 실행할 때 JAVA_TOOL_OPTIONS 환경 변수 설정을 해제합니다.
    • 해결 방법 2: JAyatana를 제거합니다.
  • 네이티브 코드를 디버깅하는 동안 자바 중단점 추가: 앱이 네이티브 코드의 중단점에서 일시중지된 동안 자동듀얼 디버거가 새롭게 설정된 자바 중단점을 즉시 인식하지 못할 수 있습니다. 이 문제를 방지하려면 디버그 세션을 시작하기 전에 또는 자바 중단점에서 앱이 일시중지된 상태에서 자바 중단점을 추가합니다. 자세한 내용은 문제 229949를 참조하세요.

  • 네이티브 디버거에서 나가기: 자바 및 네이티브 코드를 디버그하는 데 자동 또는 듀얼 디버거를 사용하는 동안 자바 코드에서 네이티브 함수로 들어갔으며(예: 네이티브 함수를 호출하는 자바 코드 줄에서 디버거가 실행을 일시중지하고 개발자가 Step Into를 클릭함) 자바 코드로 돌아가고 싶은 경우 Step Out 또는 Step Over 대신 Resume Program 을 클릭합니다. 앱 프로세스는 여전히 일시중지되어 있으므로 your-module-java 탭에서 Resume Program 을 클릭하여 프로세스를 다시 시작합니다. 자세한 내용은 문제 224385를 참조하세요.

  • 잘못된 렌더링 예외: 특정 렌더링 오류 메시지는 다음과 같습니다. '다음 클래스를 찾을 수 없음: - android.support.v7.internal.app.WindowDecorActionBar'. 이 오류 메시지가 표시되어도 레이아웃 미리보기는 올바르며 오류 메시지를 무시해도 괜찮습니다.

    이 문제는 Android 스튜디오 2.0 미리보기부터 해결되었습니다.

  • macOS High Sierra의 Android 에뮬레이터 HAXM: macOS High Sierra(10.13)의 Android 에뮬레이터가 macOS와 가장 잘 호환되고 안정적으로 작동하려면 HAXM 6.2.1+가 필요합니다. 그러나 macOS 10.13에는 HAXM과 같은 커널 확장자를 설치하는 더 복잡한 프로세스가 있습니다. 다음과 같이 커널 확장자가 설치될 수 있도록 수동으로 허용해야 합니다.

    1. 먼저 SDK Manager에서 최신 버전의 HAXM을 설치합니다.
    2. macOS에서 System Preferences(시스템 환경설정) > Security and Privacy(보안 및 개인 정보 보호)로 이동합니다.
    3. 개발자 'Intel Corporation Apps'의 시스템 소프트웨어가 차단되어 로드할 수 없습니다라는 경고가 표시되면 Allow(허용)를 클릭합니다.

    자세한 내용과 해결 방법은 이 Apple 웹페이지문제 62395878을 참조하세요.

Android Gradle 플러그인의 알려진 문제

  • Gradle 4.6 이상의 주문형 구성: Gradle 4.6 이상에서 Android Gradle 플러그인 3.0.x 또는 3.1.x를 사용하는 경우 일부 예측할 수 없는 빌드 오류가 발생하지 않도록 주문형 구성을 사용 중지해야 합니다. (Android Gradle 플러그인 3.2.0 이상을 사용하는 경우 주문형 구성을 사용 중지하기 위해 어떠한 조치도 취할 필요가 없습니다.)

    아래와 같이 gradle.properties 파일에서 주문형 구성을 사용 중지합니다.

    org.gradle.configureondemand=false
        

    Android 스튜디오 설정에서 주문형 구성을 사용 중지하려면 File > Settings(Mac의 경우 Android Studio > Preferences)를 선택하고 왼쪽 창에서 Compiler 카테고리를 선택한 다음 Configure on demand 체크박스를 선택 해제합니다.

    Android 스튜디오 3.2 베타 1 이상에서는 주문형 구성을 사용하는 옵션이 삭제되었습니다.

  • Android 플러그인 3.0.0을 여러 번 로드하는 동안의 프로젝트 동기화 오류: 하나의 빌드에서 Android 플러그인을 여러 번 로드하면 프로젝트 동기화 오류가 발생합니다. 이 오류는 여러 하위 프로젝트가 있고 각각의 빌드스크립트 클래스 경로에 Android 플러그인이 포함되어 있을 때 발생할 수 있습니다. 이는 Gradle의 새로운 변형을 인식하는 종속성 관리의 제한 사항으로, 아직 다른 클래스로더에서 매칭되는 속성을 처리할 수 없습니다. Android 플러그인 3.0.0 이하를 사용하는 경우 플러그인을 Android 플러그인 3.1.0 이상으로 업그레이드하거나 아래 단계에 따라 문제를 해결하세요.

    • 다중 모듈 빌드: 아래와 같이 최상위 build.gradle 파일의 빌드 클래스 경로에만 Android 플러그인을 추가해야 합니다.

      // Additionally, make sure that you don't wrap this in a
          // subprojects block.
          buildscript {
              ...
              dependencies {
                  classpath 'com.android.tools.build:gradle:3.4.2'
              }
          }
          
    • 합성 빌드: 메인 프로젝트와 Android 플러그인을 사용하는 각 포함된 프로젝트에서 빌드스크립트 클래스 경로가 동일해야 합니다. 또한, buildscript 블록에 추가하는 클래스 경로의 순서가 동일해야 합니다. 예를 들어, 메인 프로젝트의 build.gradle 파일에 포함된 다음의 클래스 경로 종속성을 고려해보세요.

      buildscript {
              ...
              dependencies {
                  classpath "com.android.tools.build:gradle:3.4.2"
                  classpath "me.tatarka:gradle-retrolambda:3.7.0"
              }
          }
          

      이제 합성 빌드에 포함된 또 다른 프로젝트에 대해 다음의 build.gradle 파일을 고려해보세요.

      buildscript {
              dependencies {
                  // Note that the order of plugins differs from that
                  // of the main project's build.gradle file. This results
                  // in a build error because Gradle registers this as a
                  // different classloader.
                  classpath "me.tatarka:gradle-retrolambda:3.7.0"
                  classpath "com.android.tools.build:gradle:3.4.2"
              }
          }
          
  • Firebase 플러그인 버전 1.1.0의 Guava 종속성 불일치: Firebase 플러그인 버전 1.1.0에서는 Guava 종속성에 불일치가 발생하여 다음과 같은 오류가 발생할 수 있습니다.

        Error:Execution failed for task ':app:packageInstantRunResourcesDebug'.
        com.google.common.util.concurrent.MoreExecutors.directExecutor()Ljava/util/concurrent/Executor;
        
    이 빌드 오류를 해결하려면 프로젝트 수준 build.gradle 파일의 dependencies 블록에 다음을 추가합니다.

    dependencies {
            classpath ('com.google.firebase:firebase-plugins:1.1.0') {
                        exclude group: 'com.google.guava', module: 'guava-jdk5'
            }
            ...
        }
        

    자세한 내용은 문제 #63180002를 참조하세요.

  • Protobufs를 사용하려면 Protobuf 플러그인을 버전 0.8.2 이상으로 업그레이드해야 합니다.

  • 타사 android-apt 플러그인은 더 이상 지원되지 않습니다. 기본 제공 주석 프로세서 지원으로 전환해야 합니다. 이 지원은 종속성 해결을 느슨하게 처리하도록 개선되었습니다.

  • JAR 서명(v1 체계)은 캐리지 리턴(CR) 문자가 포함된 파일 이름은 지원하지 않습니다. (문제 744 참조)

API 변경사항

Android Gradle 플러그인 3.0.0 이상에 도입된 API 변경사항은 특정 기능을 삭제하며 기존 빌드를 손상시킬 수 있습니다. 이후 버전의 플러그인에서는 손상된 기능을 대체하는 새로운 공개 API가 도입될 수도 있습니다.

빌드 시점에서 변형 출력 수정이 작동하지 않을 수 있음

Variant 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.
    

각 변형의 manifest 파일을 가져오기 위해 manifestOutputFile()을 호출하는 대신 생성된 모든 manifest가 포함된 디렉터리의 경로를 반환하기 위해 processManifest.manifestOutputDirectory()를 호출할 수 있습니다. 그런 다음, manifest를 찾아 여기에 로직을 적용할 수 있습니다. 아래 샘플은 manifest에서 버전 코드를 동적으로 변경합니다.

    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)
            }
        }
    }