동작 변경사항: 모든 앱

Android 10에는 앱에 영향을 줄 수 있는 동작 변경사항이 포함되어 있습니다. 이 페이지에 나열된 변경사항은 앱의 targetSdkVersion과 관계없이 Android 10에서 실행될 때 앱에 적용됩니다. 이러한 변경사항을 적절히 지원하려면 앱을 테스트하고 필요에 따라 수정해야 합니다.

앱의 targetSdkVersion이 29 이상인 경우 추가 변경사항을 지원해야 합니다. 자세한 내용은 29를 타겟팅하는 앱의 동작 변경사항을 참고하세요.

참고: 이 페이지에 나열된 변경사항 외에도 Android 10에는 다음을 비롯하여 여러 개인 정보 보호 기반 변경사항 및 제한사항이 도입되었습니다.

  • 기기 위치에 대한 백그라운드 액세스
  • 백그라운드 활동 시작
  • 연락처 어피니티 정보
  • 무작위 MAC 주소
  • 카메라 메타데이터
  • 권한 모델

이 변경사항은 모든 앱에 영향을 미치며 사용자 개인 정보 보호를 강화합니다. 이러한 변경사항을 지원하는 방법에 관한 자세한 내용은 개인 정보 보호 변경사항 페이지를 참고하세요.

비 SDK 인터페이스 제한사항

앱 안정성과 호환성을 보장하기 위해 플랫폼에서는 Android 9 (API 수준 28)에서 앱이 사용할 수 있는 비 SDK 인터페이스를 제한하기 시작했습니다. Android 10에는 Android 개발자와의 공동작업 및 최신 내부 테스트를 기반으로 제한된 비 SDK 인터페이스의 업데이트된 목록이 포함되어 있습니다. Google의 목표는 비 SDK 인터페이스를 제한하기 전에 공개 대안을 사용할 수 있도록 하는 것입니다.

Android 10 (API 수준 29)을 타겟팅하지 않는 경우 이러한 변경사항 중 일부는 개발자에게 곧바로 영향을 주지 않을 수도 있습니다. 그러나 앱의 대상 API 수준에 따라 현재 일부 비 SDK 인터페이스를 사용할 수 있지만 비 SDK 메서드 또는 필드를 사용하면 언제든지 앱이 중단될 위험이 있습니다.

앱에서 비 SDK 인터페이스를 사용하는지 확실하지 않으면 앱을 테스트하여 확인할 수 있습니다. 앱에서 비 SDK 인터페이스를 사용하는 경우 대체 SDK로 이전을 계획해야 합니다. 일부 앱의 경우 비 SDK 인터페이스 사용에 관한 유효한 사용 사례가 있음을 알고 있습니다. 앱 기능을 구현하기 위해 비 SDK 인터페이스 대신 무엇을 사용해야 할지 알 수 없다면 새 공개 API를 요청해야 합니다.

자세한 내용은 Android 10의 비 SDK 인터페이스 제한사항 업데이트비 SDK 인터페이스 제한사항을 참고하세요.

동작 탐색

Android 10부터 사용자는 기기 전반에서 동작 탐색을 사용할 수 있습니다. 사용자가 동작 탐색을 사용 설정하면 앱이 API 수준 29를 타겟팅하는지와 관계없이 기기의 모든 앱이 영향을 받습니다. 예를 들어 사용자가 화면 가장자리에서 안쪽으로 스와이프하면 앱이 화면의 일부에 관해 해당 동작을 특별히 재정의하는 경우가 아니면 시스템이 해당 동작을 뒤로 탐색으로 해석합니다.

앱이 동작 탐색과 호환되도록 하려면 앱 콘텐츠를 가장자리까지 확장하고 충돌하는 동작을 적절하게 처리하는 것이 좋습니다. 자세한 내용은 동작 탐색 문서를 참고하세요.

NDK

Android 10에는 다음과 같은 NDK 변경사항이 있습니다.

공유 객체에는 텍스트 재배치가 포함될 수 없습니다.

Android 6.0 (API 수준 23)에서는 공유 객체에서 텍스트 재배치를 사용하는 것을 허용하지 않았습니다. 코드를 있는 그대로 로드해야 하며 수정해서는 안 됩니다. 이러한 변경으로 인해 앱 로드 시간이 단축되고 보안이 향상됩니다.

SELinux는 Android 10 이상을 타겟팅하는 앱에 이 제한을 적용합니다. 이러한 앱에서 텍스트 재배치가 포함된 공유 객체를 계속 사용하면 중단될 위험이 높습니다.

Bionic 라이브러리 및 동적 링커 경로 변경사항

Android 10부터 여러 경로가 일반 파일이 아닌 심볼릭 링크입니다. 일반 파일인 경로를 사용한 앱은 중단될 수 있습니다.

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

이러한 변경사항은 lib/lib64/로 바뀌는 파일의 64비트 변형에도 적용됩니다.

호환성을 위해 이전 경로에서 심볼릭 링크가 제공됩니다. 예를 들어 /system/lib/libc.so/apex/com.android.runtime/lib/bionic/libc.so의 심볼릭 링크입니다. 따라서 dlopen(“/system/lib/libc.so”)는 계속 작동하지만, 앱이 /proc/self/maps 또는 이와 유사한 항목을 읽어 실제로 로드된 라이브러리를 검사하려고 하면 차이를 발견하게 됩니다. 이는 일반적이지는 않지만 일부 앱은 해킹 방지 프로세스의 일부로 이 작업을 실행하는 것으로 확인되었습니다. 이런 경우, /apex/… 경로가 Bionic 파일의 유효한 경로로 추가되어야 합니다.

실행 전용 메모리에 매핑된 시스템 바이너리/라이브러리

Android 10부터 시스템 바이너리 및 라이브러리의 실행 가능 세그먼트는 코드 재사용 공격에 대비한 강화 기법으로 메모리 실행 전용 (읽기 불가능)으로 매핑됩니다. 앱이 버그, 취약성 또는 의도적 메모리 검사 중에 실행 전용으로 표시된 메모리 세그먼트에서 읽기 작업을 수행하면 시스템은 앱에 SIGSEGV 신호를 보냅니다.

/data/tombstones/에서 관련 Tombstone 파일을 검사하여 이 동작이 비정상 종료의 원인인지 식별할 수 있습니다. 실행 전용 관련 비정상 종료에는 다음과 같은 중단 메시지가 포함됩니다.

Cause: execute-only (no-read) memory access error; likely due to data in .text.

이 문제를 해결하여 메모리 검사와 같은 작업을 수행하려면 mprotect()를 호출하여 실행 전용 세그먼트를 읽기+실행으로 표시할 수 있습니다. 그러나 이 액세스 권한 설정이 앱과 사용자를 더 잘 보호하므로 나중에 다시 실행 전용으로 설정하는 것이 좋습니다.

보안

Android 10의 보안 변경사항은 다음과 같습니다.

TLS 1.3 기본 사용 설정

Android 10 이상에서는 모든 TLS 연결에서 TLS 1.3이 기본적으로 사용 설정됩니다. 다음은 TLS 1.3 구현에 관한 몇 가지 중요한 세부정보입니다.

  • TLS 1.3 암호화 스위트는 맞춤설정할 수 없습니다. TLS 1.3을 사용 설정하면 지원되는 TLS 1.3 암호화 스위트가 항상 사용 설정됩니다. setEnabledCipherSuites()를 호출하여 이를 사용 중지하려는 시도는 모두 무시됩니다.
  • TLS 1.3이 협상되면 세션이 세션 캐시에 추가되기 전에 HandshakeCompletedListener 객체가 호출됩니다. (TLS 1.2 및 기타 이전 버전에서는 세션이 세션 캐시에 추가된 후에 이러한 객체가 호출됩니다.)
  • SSLEngine 인스턴스가 이전 버전의 Android에서 SSLHandshakeException을 발생시키는 일부 상황에서 이러한 인스턴스는 Android 10 이상에서 대신 SSLProtocolException을 발생시킵니다.
  • 0-RTT 모드는 지원되지 않습니다.

원하는 경우 SSLContext.getInstance("TLSv1.2")를 호출하여 TLS 1.3이 사용 중지된 SSLContext를 가져올 수 있습니다. 또한 적절한 객체에서 setEnabledProtocols()를 호출하여 연결별로 프로토콜 버전을 사용 설정 또는 사용 중지할 수 있습니다.

SHA-1로 서명된 인증서가 TLS에서 신뢰되지 않음

Android 10에서 SHA-1 해시 알고리즘을 사용하는 인증서는 TLS 연결에서 신뢰되지 않습니다. 루트 CA는 2016년 이후 이러한 인증서를 발급하지 않았으며 Chrome 또는 기타 주요 브라우저에서 더 이상 신뢰되지 않습니다.

SHA-1을 사용하여 인증서를 제공하는 사이트에 연결하는 경우 연결 시도가 실패합니다.

KeyChain 동작 변경사항 및 개선사항

Chrome과 같은 일부 브라우저에서는 TLS 서버가 TLS 핸드셰이크의 일부로 인증서 요청 메시지를 보낼 때 인증서를 선택할 수 있습니다. Android 10부터 KeyChain 객체는 KeyChain.choosePrivateKeyAlias()를 호출하여 사용자에게 인증서 선택 메시지를 표시할 때 발급기관과 키 사양 매개변수를 준수합니다. 특히 이 프롬프트에는 서버 사양을 준수하지 않는 선택사항이 포함되지 않습니다.

서버 사양과 일치하는 인증서가 없거나 기기에 인증서가 설치되지 않은 경우와 같이 사용자가 선택할 수 있는 사용 가능한 인증서가 없는 경우 인증서 선택 메시지가 아예 표시되지 않습니다.

또한 Android 10 이상에서는 키 또는 CA 인증서를 KeyChain 객체로 가져오기 위해 기기 화면 잠금이 필요하지 않습니다.

기타 TLS 및 암호화 변경사항

Android 10에 적용되는 TLS 및 암호화 라이브러리에서 사소한 몇 가지 사항이 변경되었습니다.

  • AES/GCM/NoPadding 및 ChaCha20/Poly1305/NoPadding 암호화는 getOutputSize()에서 더욱 정확한 버퍼 크기를 반환합니다.
  • TLS_FALLBACK_SCSV 암호화 제품군은 최대 프로토콜 TLS 1.2 이상의 연결 시도에서 생략됩니다. TLS 서버 구현이 향상되었으므로 TLS 외부 대체를 시도하지 말고, 대신 TLS 버전 협상에 의존하는 것이 좋습니다.
  • ChaCha20-Poly1305는 ChaCha20/Poly1305/NoPadding의 별칭입니다.
  • 끝에 점이 있는 호스트 이름은 유효한 SNI 호스트 이름으로 간주되지 않습니다.
  • 인증서 응답용 서명 키를 선택할 때 CertificateRequest의 supported_signature_algorithms 확장이 고려됩니다.
  • TLS에서 RSA-PSS와 함께 불투명한 서명 키(예: Android 키 저장소의 서명 키)를 사용할 수 있습니다.

Wi-Fi Direct 방송

Android 10에서는 Wi-Fi Direct와 관련된 다음 방송이 고정되지 않습니다.

브로드캐스트가 고정되었기 때문에 등록 시 앱에서 이러한 브로드캐스트를 수신하는 데 의존했다면 대신 초기화 시 적절한 get() 메서드를 사용하여 정보를 얻습니다.

Wi-Fi Aware 기능

Android 10에는 Wi-Fi Aware 데이터 경로를 사용하여 TCP/UDP 소켓을 쉽게 만들 수 있는 지원이 추가되었습니다. ServerSocket에 연결하는 TCP/UDP 소켓을 만들려면 클라이언트 기기에서 서버의 IPv6 주소와 포트를 알아야 합니다. 이전에는 BT 또는 Wi-Fi Aware 레이어 2 메시지 사용 등 대역 외 커뮤니케이션 또는 mDNS와 같은 다른 프로토콜을 사용하는 대역 내 검색에 필요했습니다. Android 10에서는 네트워크 설정의 일부로 정보가 전달될 수 있습니다.

서버는 다음 중 하나를 할 수 있습니다.

  • ServerSocket를 초기화하고 사용할 포트를 설정하거나 가져옵니다.
  • Wi-Fi Aware 네트워크 요청의 일부로 포트 정보를 지정합니다.

다음 코드 샘플은 네트워크 요청의 일부로 포트 정보를 지정하는 방법을 보여줍니다.

Kotlin

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

자바

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(some-password)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

그런 다음 클라이언트에서 Wi-Fi Aware 네트워크 요청을 수행하여 서버에서 제공하는 IPv6 및 포트를 가져옵니다.

Kotlin

val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

자바

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

Go 기기의 SYSTEM_ALERT_WINDOW

Android 10 (Go 버전) 기기에서 실행되는 앱은 SYSTEM_ALERT_WINDOW 권한을 받을 수 없습니다. 이는 그리기 오버레이 창에서 메모리가 과도하게 사용되어 메모리가 부족한 Android 기기의 성능에 특히 악영향을 미치기 때문입니다.

Android 9 이하를 실행하는 Go 버전 기기에서 실행되는 앱이 SYSTEM_ALERT_WINDOW 권한을 받는 경우 기기가 Android 10으로 업그레이드되어도 앱의 권한이 유지됩니다. 그러나 아직 이 권한이 없는 앱은 기기를 업그레이드한 후 권한을 부여받을 수 없습니다.

Go 기기의 앱이 ACTION_MANAGE_OVERLAY_PERMISSION 작업이 포함된 인텐트를 전송하면 시스템은 요청을 자동으로 거부하고 사용자를 설정 화면으로 이동시킵니다. 이 화면에는 기기 속도가 느려지기 때문에 권한이 허용되지 않는다고 표시됩니다. Go 기기의 앱이 Settings.canDrawOverlays()를 호출하는 경우 이 메서드는 항상 false를 반환합니다. 다시 말하지만, 기기를 Android 10으로 업그레이드하기 전에 SYSTEM_ALERT_WINDOW 권한을 부여받은 앱에는 이러한 제한이 적용되지 않습니다.

이전 Android 버전을 대상으로 하는 앱에 대한 경고

Android 10 이상을 실행하는 기기는 Android 5.1 (API 수준 22) 이하를 타겟팅하는 앱을 처음 실행할 때 사용자에게 경고를 표시합니다. 앱에서 사용자에게 권한을 허용하도록 요청하는 경우 사용자는 앱을 처음으로 실행하도록 허용하기 전에 앱의 권한을 조정할 수 있습니다.

Google Play의 타겟 API 요구사항 때문에 사용자가 최근에 업데이트되지 않은 앱을 실행하는 경우에만 이러한 경고가 표시됩니다. 다른 스토어를 통해 배포되는 앱에는 2019년 중에 비슷한 타겟 API 요구사항을 적용할 예정입니다. 이러한 요구사항에 관한 자세한 내용은 2019년의 대상 API 수준 요구사항 확장을 참고하세요.

SHA-2 CBC 암호화 제품군 제거

다음 SHA-2 CBC 암호화 제품군이 플랫폼에서 제거되었습니다.

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

이 암호화 제품군은 GCM을 사용하는 유사한 암호화 제품군보다 덜 안전하며 대부분의 서버에서는 이러한 암호화 제품군의 GCM 및 CBC 변형을 모두 지원하거나 둘 중 어느 것도 지원하지 않습니다.

앱 사용

Android 10에서는 앱 사용과 관련하여 다음과 같은 동작이 변경되었습니다.

  • UsageStats 앱 사용량 개선 - Android 10에서는 앱이 화면 분할 또는 PIP 모드에서 사용될 때 UsageStats로 앱 사용량을 정확하게 추적합니다. 또한 Android 10은 인스턴트 앱 사용을 올바르게 추적합니다.

  • 앱별 그레이 스케일 - Android 10은 앱 단위로 그레이 스케일 표시 모드를 설정할 수 있습니다.

  • 앱별 주의 분산 상태 - 이제 Android 10에서는 앱에 알림이 표시되지 않고 앱이 추천 앱으로 표시되지 않는 '주의 분산 상태'로 앱을 선택적으로 설정할 수 있습니다.

  • 일시중지 및 재생 - Android 10에서는 일시중지된 앱이 오디오를 재생할 수 없습니다.

HTTPS 연결 변경

Android 10을 실행하는 앱이 nullsetSSLSocketFactory()에 전달하면 IllegalArgumentException이 발생합니다. 이전 버전에서는 nullsetSSLSocketFactory()에 전달하는 것이 현재의 기본 팩토리를 전달하는 것과 동일했습니다.

android.preference 라이브러리 지원 중단

Android 10부터 android.preference 라이브러리가 지원 중단됩니다. 개발자는 Android Jetpack의 일부인 AndroidX preference 라이브러리를 대신 사용해야 합니다. 이전 및 개발 지원용 추가 리소스는 업데이트된 설정 가이드와 함께 공개 샘플 앱참조 문서를 확인하세요.

ZIP 파일 유틸리티 라이브러리 변경사항

Android 10에서는 ZIP 파일을 처리하는 java.util.zip 패키지의 클래스에 다음과 같은 변경사항이 도입되었습니다. 이러한 변경으로 Android 및 java.util.zip을 사용하는 다른 플랫폼 사이에 라이브러리 동작의 일관성이 더욱 향상되었습니다.

Inflater

이전 버전에서는 Inflater 클래스의 일부 메서드가 end() 호출 후에 호출되면 IllegalStateException을 발생시켰습니다. Android 10에서는 이러한 메서드가 NullPointerException을 대신 발생시킵니다.

ZipFile

Android 10 이상에서는 File, int, Charset 유형의 인수를 사용하는 ZipFile 생성자가 제공된 ZIP 파일에 파일이 포함되어 있지 않은 경우 ZipException을 발생시키지 않습니다.

ZipOutputStream

Android 10 이상에서는 파일이 포함되지 않은 ZIP 파일의 출력 스트림을 작성하려고 할 때 ZipOutputStreamfinish() 메서드가 ZipException을 발생시키지 않습니다.

카메라 변경사항

카메라를 사용하는 많은 앱에서는 기기가 세로 모드로 구성된 경우 카메라 방향에 설명된 대로 실제 기기도 세로 방향이라고 가정합니다. 이전에는 이러한 가정이 안전했지만 폴더블과 같은 사용 가능한 폼 팩터가 확장되면서 바뀌었습니다. 이러한 기기에서 이러한 가정으로 인해 카메라 뷰파인더 디스플레이가 잘못 회전하거나 크기가 조정 (또는 둘 다)될 수 있습니다.

API 수준 24 이상을 타겟팅하는 애플리케이션은 android:resizeableActivity를 명시적으로 설정하고 멀티 윈도우 작업을 처리하는 데 필요한 기능을 제공해야 합니다.

배터리 사용량 추적

Android 10부터 SystemHealthManager주요 충전 이벤트 후 기기가 전원에서 분리될 때마다 배터리 사용량 통계를 재설정합니다. 일반적으로 주요 충전 이벤트란 기기가 완전히 충전되었거나 기기의 배터리가 거의 소모된 상태에서 대부분 충전된 상태가 된 것을 말합니다.

Android 10 이전에는 배터리 수준에 거의 변화가 없어도 기기가 전원에서 분리될 때마다 배터리 사용량 통계가 재설정되었습니다.

Android Beam 지원 중단

Android 10에서는 근거리 무선통신 (NFC)을 통해 기기 간 데이터 공유를 시작하기 위한 이전 기능인 Android Beam이 공식적으로 지원 중단됩니다. 또한 몇 가지 관련된 NFC API도 지원 중단됩니다. Android Beam을 사용하려는 기기 제조업체 파트너는 선택적으로 사용할 수 있지만, 더 이상 개발에는 포함되지 않습니다. 그러나 Android는 다른 NFC 기능 및 API를 계속 지원하며, 태그 및 결제에서 읽기와 같은 사용 사례는 계속 예상대로 작동합니다.

java.math.BigDecimal.stripTrailingZeros() 동작 변경

BigDecimal.stripTrailingZeros()는 입력 값이 0인 경우 더 이상 특수 사례로 뒤의 0을 유지하지 않습니다.

java.util.regex.Matcher 및 패턴 동작 변경사항

입력 시작 부분에 너비가 0인 일치가 있는 경우 더 이상 빈 String("")로 시작하지 않도록 split()의 결과가 변경되었습니다. 이는 String.split()에도 영향을 미칩니다. 예를 들어 이전 버전의 Android에서는 "x".split(""){"", "x"}를 반환했지만 이제는 {"x"}를 반환합니다. 이제 "aardvark".split("(?=a)"{"", "a", "ardv", "ark"} 대신 {"a", "ardv", "ark"}를 반환합니다.

잘못된 인수의 예외 동작도 개선되었습니다.

  • 교체 String가 고독한 백슬래시로 끝나면 appendReplacement(StringBuffer, String)에서 이제 IndexOutOfBoundsException 대신 IllegalArgumentException이 발생합니다. 이는 불법입니다. 이제 교체 String$로 끝나는 경우 동일한 예외가 발생합니다. 이전에는 이 시나리오에서 예외가 발생하지 않았습니다.
  • replaceFirst(null)NullPointerException을 발생시키면 더 이상 Matcher에서 reset()를 호출하지 않습니다. 이제 일치하는 항목이 없을 때도 NullPointerException이 발생합니다. 이전에는 일치하는 경우에만 발생했습니다.
  • 이제 그룹 색인이 범위를 벗어나면 start(int group), end(int group), group(int group)에서 더 일반적인 IndexOutOfBoundsException이 발생합니다. 이전에는 이러한 메서드에서 ArrayIndexOutOfBoundsException이 발생했습니다.

GradientDrawable의 기본 각도는 이제 TOP_BOTTOM입니다.

Android 10에서 XML에 GradientDrawable를 정의하고 각도 측정을 제공하지 않으면 그라데이션 방향이 기본적으로 TOP_BOTTOM로 설정됩니다. 이전 버전의 Android에서는 기본값이 LEFT_RIGHT였지만 이번에 변경되었습니다.

이 문제를 해결하려면 최신 버전의 AAPT2로 업데이트하면 도구에서 각도 측정이 지정되지 않은 경우 기존 앱의 각도 측정값을 0으로 설정합니다.

기본 SUID를 사용하여 직렬화된 객체 로깅

Android 7.0 (API 수준 24)부터 플랫폼은 직렬화 가능한 객체의 기본 serialVersionUID를 수정했습니다. 이 수정사항은 API 수준 23 이하를 타겟팅하는 앱에는 영향을 미치지 않았습니다.

Android 10부터 앱이 API 수준 23 이하를 타겟팅하고 잘못된 이전 기본 serialVersionUID를 사용하는 경우 시스템은 경고를 기록하고 코드 수정을 제안합니다.

특히 다음 조건이 모두 충족되면 시스템에서 경고를 기록합니다.

  • 앱이 API 수준 23 이하를 타겟팅합니다.
  • 클래스가 직렬화됩니다.
  • 직렬화된 클래스는 serialVersionUID를 명시적으로 설정하는 대신 기본 serialVersionUID를 사용합니다.
  • 기본 serialVersionUID는 앱이 API 수준 24 이상을 타겟팅하는 경우의 serialVersionUID와 다릅니다.

이 경고는 영향을 받는 클래스마다 한 번씩 기록됩니다. 경고 메시지에는 serialVersionUID를 앱이 API 수준 24 이상을 타겟팅하는 경우 계산되는 기본값으로 명시적으로 설정하는 것이 좋습니다. 이 수정사항을 사용하면 해당 클래스의 객체가 API 수준 23 이하를 타겟팅하는 앱에서 직렬화되면 24 이상을 타겟팅하는 앱에서 객체를 올바르게 읽을 수 있고 그 반대의 경우도 마찬가지입니다.

java.io.FileChannel.map() 변경사항

Android 10부터 truncate()를 사용하여 크기를 변경할 수 없는 비표준 파일(예: /dev/zero)에는 FileChannel.map()가 지원되지 않습니다. Android의 이전 버전은 truncate()에 의해 반환된 오류를 표시하지 않았지만 Android 10은 IOException을 표시합니다. 이전 동작이 필요하면 네이티브 코드를 사용해야 합니다.