android Q targetSdkVerison부터 공개된 SDK API만 사용가능하다.
이에 따라 android Q를 targetSdkVersion으로 하는 application은 공식 SDK인터페이스가 아닌 기능에는 접근하지 못하도록 제한한다.(공식홈페이지 참고)
왜 비 SDK를 제한하게 되었나?
안드로이드에서 @hide annotation으로 선언한 여러 sdk(android.xxx.xxx 같은 package)의 method들이 존재한다. @hide 구문을 사용하면 android내부에서만 접근 가능하고, 외부(application)은 접근하지 못하며 공식 패키지 색인에도 노출되지 않는다. 즉, 공식적으로 application단에서 사용이 불가하도록 선언해 놓은것이다.
그러나, 많은 전세계의 개발자들이 개발 편의를 위해 @hide method를 application단에서 java의 class invokation 혹은 reflection 혹은 @hide annotation을 강제로 지우고 사용하는 일이 빈번했다.
예를 들어 Wifi mode에서 access point를 scan하는 method가 @hide startScanActive()로 선언되어있는데, application이 호출할 수 없게되어 있음. 강제로 reflection을 통해 application이 method를 호출.
이와 같은 사용 패턴을막아서 android application을 사용하는 사용자와 개발자의 환경을 개선하고 사용자의 비정상 종료 위험과 개발자의 긴급 출시 위험을 줄이기 위해 android Q 부터는 non-sdk interface를 사용하지 못하게 제한하게 되었다.(구글 공식 블로그 설명글(바로가기))
SDK와 비 SDK 인터페이스
공개 SDK인터페이스는 Android 프레임워크 패키지 색인에 문서화 되어 있다. > 패키지색인(바로가기)
상기 공식 문서화 되어있는 부분만 사용. 상기 공식 문서화 되어 있지 않은 SDK의 api들에 대해서 강제로 java reflection을 주입하여 사용하는 경우에 대해서 android Q 부터는 사용 불가하다.
블랙리스트/그레이리스트/허용 구분
android Q가 targetSdkVersion으로 사용할경우
Blacklist | 사용할 수 없는 비 SDK 인터페이스 액세스 불가하여 시스템오류 발생 |
Graylist | Light graylist : 제한되지 않은 그레이 리스트의 비 SDK인터페이스 Dark graylist : 제한된 그레이 리스트의 비 SDK인터페이스 |
허용 | 자유롭게 사용가능한 공식 문서화된 패키지들 |
제한된 비 SDK interface를 사용시 예상되는 동작
필드를 참조하는 Dalvik 명령어 | NoSuchFieldError 발생 |
메소드를 참조하는 Dalvik 명령어 | NoSuchMethodError 발생 |
Class.getDeclaredField() 또는 Class.getField()를 통한 리플렉션 | NoSuchFieldException 발생 |
Class.getDeclaredMethod(), Class.getMethod()를 통한 리플렉션 | NoSuchMethodException 발생 |
Class.getDeclaredFields(), Class.getFields()를 통한 리플렉션 | 결과에 비 SDK 구성원 없음 |
Class.getDeclaredMethods(), Class.getMethods()를 통한 리플렉션 | 결과에 비 SDK 구성원 없음 |
env->GetFieldID()를 통한 JNI | NULL이 반환되고 NoSuchFieldError 발생 |
env->GetMethodID()를 통한 JNI | NULL이 반환되고 NoSuchMethodError발생 |
앱에 비 SDK 인터페이스가 포함되어 있는지 테스트하는 방법
1.디버깅 가능한 앱을 사용한 테스트
앱을 빌드하고 Android Q os가 올라간 기기에서 앱을 실행하면 테스트를 실행하는동안 비 SDK 인터페이스에 액세스하는경우 로그 메시지를 출력.
- 선언하는 클래스, 이름, 유형(Android 런타임에서 사용하는 형식)
- 액세스 수단: 연결, 리플렉션 또는 JNI를 통해
- 비 SDK 인터페이스가 속한 목록
android studio를 통해 logcat을 사용하면 아래와 같은 로그를 확인 할 수 있고 이에 대응하여 확인 가능.
Accessing hidden field
Landroid/os/Message;->flags:I (light greylist, JNI)
2.StrictMode API를 사용한 테스트
detectNonSdkApiUsage(바로가기)를 사용. penaltyListener(바로가기)을 사용하여 비 sdk 인터페이스를 사용할 때 마다 콜백 받을 수 있음.
3.veridex 도구를 사용한 테스트
veridex 도구(바로가기)를 통해 apk를 code base로 검색, 노출
단, 아래와 같은 경우 검출 불가
- JNI(C,C++)을 통한 호출
- 리플렉션을 통한 호출의 경우 일부감지
- API수준 검사로 제한
'개발이야기 > Android' 카테고리의 다른 글
Pixel에 Android 이미지 설치할때 오류 fastboot too old; please download the latest version 해결하기 (374) | 2019.05.08 |
---|---|
안드로이드에서 외부 jar file import하는 방법 (257) | 2018.12.26 |
Custom listview의 각 item에 animation 적용하기 (373) | 2018.12.13 |
app의 강제종료로 인해 FCM cloud messaging 푸시를 받지 못하는 이유? (982) | 2018.09.12 |
[ConstraintLayout] 효과적인 ConstraintLayout 사용방법 (2169) | 2018.04.22 |
[Instance app]설치 없이 네이티브앱의 사용경험을 제공할 수 있는 방법 (1094) | 2018.04.22 |