본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] StrictMode 에 대해 다시 한번 알아보자

by 돼지왕 왕돼지 2022. 12. 29.
반응형

-

http://aroundck.tistory.com/3429

 

Android StrictMode

Android StrictMode 출처http://code.tutsplus.com/tutorials/android-best-practices-strictmode--mobile-7581http://developer.android.com/reference/android/os/StrictMode.html - android strict mode 는 2가지 category 가 있다. 하나는 thread policy 이

aroundck.tistory.com

http://aroundck.tistory.com/2074

 

[android] Strict Mode 에 대해 알아보자.

안드로이드, Strict Mode 에 대해 알아보자. 참조 : http://dev.kthcorp.com/2012/01/31/android-strict-mode-howto/ Strict Mode 가 뭐야? * Main Thread 에서 사용성을 떨어뜨리는 작업들( 대표적으로 IO )을 하지 않도록 개발

aroundck.tistory.com

기존에 위 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 을 방지한다.

 
 
-
반응형

댓글