Android - 프로세스 분리

woga·2022년 12월 3일
0

Android 공부

목록 보기
42/49
post-thumbnail

프로세스 분리

앱 프로세스는 사용 가능한 메모리에 제한이 있다. 안드로이드 버전별로 메모리 제한에 차이가 있고, 단말별로도 다르다.
허니콤부터는 android:largeHeap 옵션을 쓸 수 있지만 단말에 따라 소용이 없거나 GC 시간이 오래 걸리거나 다른 앱의 실행에 악영향을 줄 수도 있다.

분리 설정

메모리 제한 때문에 앱의 실행에 문제가 있다면 앱은 프로세스를 분리할 수 있다. 프로세스를 분리하는 것은 각 컴포넌트 별로 가능하다.

프로세스를 분리하려면 AndroidManifest.xml에서 android:process 속성에 별도 프로세스명을 지정하면 된다. 일반적으로는 속성에는 ":remote"와 같이 콜런(:)을 사용한다. 액티비티, 서비스, 콘텐트 프로바이더, 브로드캐스트 리시버 모두 프로세스를 분리하는게 가능하다.

하나의 앱에서 생성된 별도의 프로세스는 pid(process id)는 다르지만, 동일한 uid(user id)를 가지기 때문에 권한 문제없이 앱의 파일과 리소스에 접근할 수 있다.

Application도 AndroidManifest.xml에 android:process 값을 넣을 수 있는데, 이 값은 앱의 컴포넌트가 실행되는 기본 프로세스를 이야기하는 것으로 프로세스 분리와는 의미가 다르고 쓸 일이 많지 않다.
이 process에 값을 넣는 것은 시스템앱에서 가끔 사용된다.


ex) com.android.providers.media 앱 설정에서 android:process="android.process.media"
com.android.providers.telephony는 android:process="com.android.phone"으로 되어 있다.

분리가 필요할 때

  • 액티비티 자체가 메모리를 많이 사용하는 경우

예를 들어, 사진공유 앱에서 기본 카메라 앱을 실행시키지 않고 자신의 CameraActivity를 가지고 있는 경우가 있다. 이때 CameraActivity는 메모리를 많이 사용하기 때문에 별도 프로세스로 분리하는 것이 낫다.

  • 액티비티가 메모리를 많이 사용하지 않지만 동시에 서비스에서 백그라운드 스레드로 작업을 진행한다면 OutOfMemoryError가 발생할 수 있다.

서비스가 독립적인 부분이 많다면 서비스를 분리하는게 낫다. 만일 서비스에 DB 작업이 많다면 DB 락 문제 떄문에 콘텐트 프로바이더를 도입해야 아므로, 작업이 복잡해질 경우 액티비티를 분리하는 게 좋겠다. 케이스별로 다르다!

  • 앱 위젯의 사이즈가 클 때는 (4x4, 5x5 등), 앱 위젯도 프로세스 분리를 고려해야 한다.

분리된 프로세스에 Application은 새로 시작

컴포넌트의 프로세스를 분리하면 Application은 각 프로세스마다 새로 시작된다. 프로세스가 달라지면 Zygote에 의해서 fork된 이후에 ActivityThread를 새로 시작하고 Application을 새로 생성하는 것이다.

컴포넌트가 프로세스 분리되어 있더라도 Application만은 어느 프로세스에서도 한 번은 실행되어야 한다.

프로세스 분리 시 주의할 점

프로세스 간 메모리는 공유되지 않음

분리된 별도 프로세스에서는 데이터를 가져올 수 없다.
값을 공유하기 위해서 SharedPreferences 또는 DB를 사용해야 한다.

SharedPreferences 사용 시 데이터를 다시 읽어올 때 문제

SharedPreferences는 어차피 xml 파일에서 읽어오는 것이기 때문에 한 번 읽어오는 것은 문제가 되지 않는다. 그런데 다른 프로세스에서 변경한 값을 다시 가져오는 문제는 단순하지 않다. 허니콤 이후에는 getSharedPreferences 메서드를 사용할때 Context.MODE_PRIVATE이 전달되면 값을 제대로 가져올 수 없다.

물론 이 mode를 Context.MODE_MULTI_PROCESS로 바꾸기만 하면, 된다지만 마시멜로부터 이 모드 지원을 중단했다.

결론적으로는 SharedPreferences를 다시 콘텐트 프로바이더로 감싸서 다른 프로세스에서 접근하는 방법이 권장된다. 이때 갱신이 가능하게 하려면 ContentObserver를 등록해서 데이터가 변경될 때 재조회하면 된다.

profile
와니와니와니와니 당근당근

0개의 댓글