저는 안드로이드 Process 에 대해 좋지 않은 추억이 몇 개 있습니다. 이전 포스트인 '안드로이드 Back & Home 그리고 종료 버튼' 에서도 한번 이야기 했지만, 어플리케이션 실행 시 특정 Process 가 시작되고, 어플리케이션이 종료되면 해당 Process 도 종료된다고 아주 평범하게 생각하고 있었고, 다르게 말하면 Activity 의 생명 주기나, Process 의 생명 주기는 비슷하다고 생각했습니다. 사소한 이 오해가 결국 큰 결과를 불러서 어플리케이션 개발 중간 쯤에 기존 어플리케이션을 왕창 수정해야 하는 아픔을 겪게 되었습니다. 


<안드로이드 Process 는 쉽게 무덤으로 가지 않는다.> 


 안드로이드 개발자 사이트에 보면 Process 의 생명주기에 대하여 다음과 같이 나와있습니다. (문제가 터지기 전에 좀 더 자세히 살펴보았다면 좋았겠지요..)

Processes and lifecycles

The Android system tries to maintain an application process for as long as possible, but eventually it will need to remove old processes when memory runs low. To determine which processes to keep and which to kill, Android places each process into an "importance hierarchy" based on the components running in it and the state of those components. Processes with the lowest importance are eliminated first, then those with the next lowest, and so on. There are five levels in the hierarchy. The following list presents them in order of importance:

 안드로이드에서는 어플리케이션의 Process 를 가능한 유지하기 위해 노력한다고 설명 되어있습니다. 이 내용을 좀더 따지고 들면, 극단적인 메모리 부족 상황이 아니면 한번 실행된 어플리케이션 Process 는 거의 죽지 않는 다고 생각할 수 있습니다. 만일 강제로 종료되는 경우라면? 비어있는 Process 라면 모를까, 무언가 일을 수행 하고 있던 Process 의 경우 안드로이드 시스템이서 해당 프로세스르 바로 다시 시작해 버립니다. 


 따라서, Process 와 연결되어 있는 각종 변수나 객체들은 개발자가 일반적으로 생각하는 것 보다 (Activity 종료 시 다 죽을거다...라던가) 죽지 않고, 아주 아주 오랫동안 살아남게 됩니다. 그 중에 하나가, 이전 포스트에서 이야기했던 Handler 를 들 수 있습니다. 이러한 원인으로 인해, 만일 개발자가 안드로이드 어플리케이션 개발을 위해서 Static 변수를 사용하고자 할 경우, 굉장히 조심할 필요가 있습니다. 그 이유는? Static 변수의 생명 주기는 해당 어플리케이션의 Process 와 같기 때문입니다. 


 간단한 예를 들어 보겠습니다. 어플리케이션 개발자가 다음과 같은 방식으로 어플리케이션을 구성했습니다. 


 1. 파일 다운로드 진척 상황을 주기적으로 감지하는 Downloader 클래스.

 2. 파일 다운로드 진척 상황의 변화를 전달 받기 위한 Listener 인터페이스.

 3. 해당 Listener 를 구현한 파일 다운로드 상황을 GUI로 표시하는 GUI Activity. 

 

  파일 다운로드를 상황을 감지하는 클래스는 현재 다운로드 중인 파일 명, 다운로드 진척사항등의 상태 정보를 가지고 있고, 해당 클래스를 참조해야 하는 Activity 가 여러 개이기 때문에, 사용상의 편의를 위하여 Singleton 형태로 구현 하기로 하였습니다. 


  Activity 는 onResume 상황에서 Singleton 클래스로 부터 다운로드 상황을 읽어와 Progress 를 표시하고(Home키로 잠시 다른 일을 수행하다가 어플리케이션 재 진입 시) 혹시 선택되어진 파일이 없을 경우(어플리케이션 최초 진입 시) 다운로할 파일을 선택하라는 Dialog 를 표시하도록 구현되었습니다.


  일반적인 경우, 개발자는 Singleton 클래스의 초기화에 대하여 신경쓸 필요가 없습니다. 최초 어플리케이션 실행 시에 자동으로 초기화 되기 때문에,  그걸로 충분하기 때문이조. 하지만 안드로이드에서는?

 

 Static 변수로 이루어진 Downloader  클래스는 Process 가 종료되지 않는 이상 해당 값을 계속 유지 합니다. 따라서 사용자가 이 어플리케이션을 최초 실행 할 때는 정상적으로 다운로드할 파일을 선택하라는 메세지가 출력되지만, 한번 어플리케이션을 종료 한 후에는 다시는 (메모리 부족으로 Process 가 종료되기 전까지) 해당 메세지를 볼 수 없습니다.


  간단한 예라서 그다지 큰 문제가 아니라고 느껴질 수도 있습니다. 하지만, 개인적인 경험으로 미루어 볼 때, 좀 더 복잡한 State 값을 관리하는데 접근의 편리함을 이유로 Static 변수나 Singleton 을 사용하게 되면, 특히 특정 Activity 가 다양한 Intent Filter 를 지원해서 여러 다른 어플리케이션에서 해당 Activity 를 마음대로 호출 할 수 있는 상황이라면, Static 변수의 값이 예측 불허 하다는 문제는 여러가지 복잡한 오류를 발생시키곤 했습니다. 


  제가 했던 실수를 반복하지 마시고, Process 가 사라지기 전에는 Activity 혹은 다른 Class 에서 선언한 Static 변수들의 값이 그대로 유지된다는 것을 기억하시고, Static Keyword 를 사용하는데 늘 조심하시길 바랍니다.

출처 : http://blog.naver.com/huewu/110081657442

+ Recent posts