-
http://aroundck.tistory.com/3429
http://aroundck.tistory.com/2074
기존에 위 2개를 통해 strict mode 에 대해 rough 하게 알아보았는데,
이번에 새로 추가된 API 를 포함해서 다시 보기로 하였다.
-
StrictMode 는 개발도구로 실수를 하거나 고쳐야 하는 것들에 대한 주의를 주는 용도로 사용될 수 있다.
StrictMode 로 잡는 주된 실수는 main thread 에서 disk 나 network access 를 하는 것이다.
main thread 를 responsive 하게 만듬으로써 ANR 을 방지할 수 있다.
-
Application 의 onCreate 에서 설정해주는 것이 좋다.
public void onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
-
위반이 발생했을 때 무슨 동작을 할 지 결정할 수 있다.
예를 들어 penaltyLog 를 하면 logcat 으로 관련된 log 를 출력한다.
만약 발견한 것이 문제의 소지가 있다면 여러 툴을 이용해서 고치면 된다.
그러나 strict mode 에서 발견한 것을 뭐든지 고치려고 꼭 노력할 필요는 없다.
실수로 넣은 동작만을 예방하면 된다.
UI thread 에서 network 요청은 거의 대부분 문제의 소지가 있다.
-
StrictMode 는 best effort 메카니즘이기 떄문에 100% 신뢰할 수 있는 것은 아니다.
예를 들어 JNI 를 통해 main thread 에서 disk 나 network access 를 할 경우에는 detect 되지 않는다.
그리고 StrictMode 를 배포판에 사용하면 안된다.
-
ThreadPolicy 와 VMPolicy 가 있다.
ThreadPolicy
-
detect 로 시작하는 함수들을 이용해서, 감시하고자 하는 설정들을 사용할 수 있다.
penalty 로 시작하는 함수들을 이용해서 위반이 감지되었을 때 어떤 동작을 할지 명시할 수 있다.
사용하고 싶은만큼 detectXXX penaltyXXX 함수들을 호출할 수 있다.
순서는 중요하지 않다.
다음 코드를 사용하면 모든 위반에 대해 log 를 찍는다.
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build();
StrictMode.setThreadPolicy(policy);
-
!!! 주의 !!!
detectAll 을 사용할 때 주의할 것은, detectAll 이름과 맞지 않게 모든 것을 detect 하지 않는다.
OOS 기준(targetSdk 에 따라 detect 하는 것이 다르다.) diskReads, diskWrites, network, customSlowCalls, resourceMismatches, unbufferedIo 만 detect 된다.
-
detectCustomSlowCalls (API 11) : main thread 에서 너무 많은 시간을 잡아먹는 code 를 탈 경우
detectDiskReads (API 9) : main thread 에서 disk read
detectDiskWrites (API 9) : main thread 에서 disk write
detectNetwork (API 9) : main thread 에서 network 사용
detectResourceMismatches (API 23) : 정의된 resource type 과 getter call 이 일치하지 않음 ( ex) TypedArray.getInt(int, int) )
detectUnbufferedIo (API 26) : unbuffered input/output operation 을 감지한다.
-
penaltyDeath : 위반이 발생하면 crash 를 발생시킨다. penalty 중 가장 마지막에 수행된다. 그래서 logging 도 같이 걸려 있으면 logging 은 되고 crash 가 난다.
penaltyDeathOnNetwork : main thread 에서 network 사용시 crash 를 낸다. penaltyDeath 와 다르게 다른 것들보다 우선시되서 수행된다. 그리고 이 penalty 를 사용하기 위해서는 detectNetwork() 가 무조건 호출이 되어야 한다. Honeycomb 이상의 SDK 에서는 default on 이다.
penaltyDialog : 위반 발견시 dialog 를 보여준다.
penaltyDropBox : stacktrace 와 timingdata 를 위반 로그로 DropBox 에 저장해준다. beta user 를 위해 보통 사용하는 방법이다.
penaltyFlashScreen : 위반 발견시 screen 이 깜빡인다.
penaltyListener (API 28) : listener 를 달아서 위반 시 callback 을 받을 수 있다.
penaltyLog : 위반 시 system log 를 찍는다.
-
permitAll : detection 을 모두 해지시킨다.
permitCustomSlowCalls
permitDiskReads
permitDiskWrites
permitNetwork
permitResourceMismatches
permitUnbufferedIo
VMPolicy
-
VM process 안에 있는 모든 thread 에 한정되는 strict mode 규칙을 다룬다.
ThreadPolcy 와 마찬가지로 detect 로 시작하는 함수들은 감시할 내용을 정의하고,
penalty 로 시작하는 함수들은 위반 발견시 할 action 을 정의한다.
마찬가지로 정의하고 싶은 만큼 detect 와 penalty 함수들을 호출해주면 된다.
아래 코드는 모두를 detect 하고 log 를 찍는 구현이다.
StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build();
StrictMode.setVmPolicy(policy);
-
!!! 주의 !!!
detectAll 이 이름과 다르게 모두를 detect 하지 않는다.
OOS 기준 (targetSdk 에 따라 다르다.) leakedSqlLiteObjects, activityLeaks, leakedClosableObjects, leakedRegistrationObjects, FileUriExposure, cleartextNetwork, contentUriWithoutPermission, untaggedSockets 에 대해 detect 한다.
-
detectActivityLeaks (API 11) : Activity leak 을 감시
detectCleartextNetwork (API 23) : SSL/TLS 로 wrap 되지 않은 network traffic 을 감시한다. 이를 통해 cleartext data 를 network 로 전송하는 것을 막을 수 있다. penaltyDeath() 나 penaltyDeathOnCleartextNetwork() 를 통해 socket 으로 data 가 세어 나가는 것을 막을 수 있다. 물론 crash 도 낸다. IPv4/IPv6 와 TCP/UDP 모두 감시한다.STARTTLS protocol 이나 HTTP proxy 가 사용될 경우는 잘못된 위반을 detect 할 수도 있다.
detectContentUriWithoutPermission (API 26) : content:// Uri 를 다른 앱에 전달할 때 Intent.FLAG_GRANT_READ_URI_PERMISSION 이나 Intent.FLAG_GRANT_WRITE_URI_PERMISSION 을 하지 않는 경우를 감시한다.
detectFileUriExposure (API 18) : file:// Uri 가 다른 앱에 노출되었을 때를 감시한다. 이는 shared path 에 대한 접근권한이 받는 앱에서 없을 수 있기 때문에 file uri 가 나가는 것은 추천되지 않는다. (READ_EXTERNAL_STORAGE 권한이 없는 앱이 해당 uri 를 받으면 접근할 수 없다.) file uri 대신 content uri 를 사용하면서 임시 권한을 부여해서 전달해야 한다.
detectLeakedClosableObjects (API 11) : Closable 이 method 종료시 close 되지 않을 경우 발생한다.
detectLeakedRegistrationObjects (API 16) : BroadcastReceiver 나 ServiceConnection 이 Context 정리시에 leak 발생하는 것을 감시한다.
detectLeakedSqlLiteObjects (API 9) : SQLiteCursor 나 다른 SQLite object 들이 close 되지 않는 것을 감시한다.
detectNonSdkApiUsage (API 28) : public 이 아닌 API 를 reflection 을 이용하여 사용하는 경우를 감시한다. 이 녀석이 enable 되기 전에 사용된 녀석들은 감지되지 않는다. 그러므로 최대한 빨리 이 녀석을 설정하는 것이 좋다.
detectUntaggedSockets (API 26) : TrafficStats 를 사용하여 tag 되지 않는 socket 이 있는 것을 감지한다. socket tagging 은 network 사용을 분석할 때 좋다. 현재 native code 에서 생성한 socket 에 대해서는 감지하지 않는다.
-
penaltyDeath
penaltyDeathOnCleartextNetwork
penaltyDeathOnFileUriExposure
penaltyDropBox
penaltyListener
penaltyLog
-
permitNonSdkApiUsage : 이는 StrictMode 에만 한정된다.
setClassInstanceLimit : 특정 class 가 memory 에 몇번 있을 수 있는지 상한선을 지정할 수 있다. object leak 을 방지한다.
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] Runtime permission group 에 대한 이야기 (0) | 2022.12.31 |
---|---|
[android] implicit broadcast - signature permission or FLAG_RECEIVVER_INCLUDE_BACKGROUND (0) | 2022.12.30 |
[android] FilePath 에 대한 이야기 (0) | 2022.12.28 |
[android] ListView, RecyclerView 에서 top position 인지 판단하는 방법 (0) | 2022.12.27 |
[android] AudioFocus 관리하기 (1) | 2022.02.14 |
댓글