StrictMode는 Main Thread 에서 일어날 수 있는 일을 감지하고 문제를 해결할 수 있도록 해주는 개발자 도구입니다.

StrickMode는 Main Thread 에서 Disk 입출력 또는 Network 액세스 같은 속도가 느려질 수 있는 동작을 하는 것을 감지하는데 가장 일반적으로 사용됩니다.

오래 걸릴 수 있는 작업을 Main Thread 분리하여 ANR(Android Not Response)를 방지할 수  있도록 미리 탐지합니다.

 

* Main Thread 의 작업

  안드로이드의 Callback과 lifecycle 관련 이벤트들은 모두 Main Thread에서 처리됨

  Application의 경우 Main Thread 에서 Animation, Scroll 작업에 대한 Callback을 처리함.

  I/O 작업에 걸리는 시간만큼 UI 반응이 지연됨

 

* Disk I/O 작업

  파편화된 블록 모으기 작업을 수행하는 동안 지연 발생 가능성 있음

  다른 프로세스가 오랜 시간이 걸리는 삭제 작업을 진행하면 다른 프로세스의 I/O 작업은 지연됨

  메모리 여유 공간이 적을 수록 I/O 작업이 지연됨

 

* 네트워크는 예측 불가능하므로 절대 Main Thread 에서 처리되면 안됨(기본적으로 정책적용됨)

 

한 스레드에 적용된 규약은 이 스레드에 접근하는 다른 스레드에도 전파됩니다.

바인더를 통해 다른 스레드 또는 다른 프로세스의 메소드를 호출할 때도 동일한 규약이 적용됩니다.

 

 

public void onCreate() {
    if (DEVELOPER_MODE) {
        StrickMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                        .detectDiskReads()
                        .detectDiskWrites()
                        .detectNetwork()
                        .penaltyLog()
                        .build());
        StrickMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                        .detectLeakedSqlLiteObjects()
                        .detectLeakedClosableObjects()
                        .panaltyLog()
                        .penaltyDeath()
                        .build());
    }
}

 

penal...() 메소드를 통해 위반이 감지될 때 어떤 일이 발생할지 결정할 수 있습니다.

penaltyLog() : Log를 통해 위반을 감지

penaltyDropbox() : DropBoxManager 에 기록

                         adb shell dumpsys sropbox data_app_strictmode --print 를 통해 내용을 확인

panaltyDeath() : crash발생

 

 

해당 Thread의 동작이 의도된 동작일 경우 아래와 같이 정책변경을 할 수 있습니다.

여러 블로그에서 Nougat(Android N-OS)부터 Main Thread 에서 Network 액세스를 차단하기 때문에 아래와 같이 해결하라고 말하고 있는데요.

정책변경 보다는 Thread 분리가 우선입니다.

 

StrickMode.ThreadPolicy tp = new StrictMode.ThreadPolicy.Builder()
        .permitDiskReads()
        .permitDiskWrites()
        .build();
StrickMode.setThreadPolicy(tp);

 

 

StrickMode.ThreadPolicy tp = new StrictMode.ThreadPolicy.Builder()
        .permitNetwork()
        .build();
StrickMode.setThreadPolicy(tp);

 

아래와 같이 StrictMode 테스트를 위해 App에서 StrictMode 정책 설정을 하고 Main Thread에서 SharedPreferences를 설정하는 코드를 적용해보았습니다.

SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("venderinfo", "aaa");
editor.apply();

 

StrictMode 정책을 penaltyLog()로 설정하였을 때 위반로그를 확인 할 수 있습니다.

SharedPreferences 와 같이 Disk I/O 작업을 수반하는 동작은 Main Thread 에서 분리하여 개발해야겠습니다.

 

Google 에서 StrickMode 정책 적용은 실제 배포할 때는 적용하지 않도록 가이드 하고 있습니다.

OS upgrade 때마다 정책변경이 발생할 수 있으므로 기존 OS에서는 정상 동작했던 것도 OS Upgrade 이후에 오동작을 유발할 수 있기 때문이라고 합니다.

 

 

 

 

+ Recent posts