본문 바로가기

Android/Process

안드로이드/Android 안드로이드 어플리케이션 Process 를 정말로 죽이는 방법

안드로이드/Android 안드로이드 어플리케이션 Process 를 정말로 죽이는 방법




Android How to Kill Application Process 
관련글: 안드로이드 어플리케이션 종료하기 (이글을 참조하시기 바랍니다.)

<개발자의 부주의로 어플리케이션이 정리되지 않는 설겆이 거리를 만들어 낼 수 있습니다..>

  안드로이드 상에서 어플리케이션 개발을 진행하다 보면, 어플리케이션 Process 자체를 종료 시키고 싶은 경우가 있습니다. 특히 제 경우에는 여러가지 핸들러나 스레드를 사용하는 경우 Process 를 종료시키고 싶을 때가 많더군요. Activity 를 모두 종료하더라도, Process 가 살아 있으면 메인 UI 스레드에 연결되어 있는 Handler 와 Message 는 쌩쌩히 동작합니다. 더군다나 시간이 오래 걸리는 작업을 수행하기 위해 Thread 를 여럿 생성해 둔 상태에서 해당 Thread 들의 라이프 사이클을 잘 관리하지 않으면 Activity 가 종료 되더라도, 죽지 않고 계속 살아 남기 때문에, 원인을 알 수 없는 오류로 어플리케이션을 죽여 먹곤 했습니다. 

  그야말로 고생해서 밥 잘 해먹은 다음에, 설겆이 하면서 그릇을 다 깨먹는 형국입니다. 성능상에 약간의 손실을 감수하더라도, 기름때가 잔뜩 묻은 접시마냥 흉칙하게 남아있는 깔끔하게 정리해 버리고자, 몇 가지 방법을 사용해봤습니다. 하지만,종료 버튼 관련 포스트에서 한번 언급했듯이, 그런 시도들이 썩 성공적이지는 않았습니다.


<드라큘라에게도 약점이 있듯이, 안드로이드 Process 도 죽이는 방법이 있습니다.>

  궁하면 통하는 법인가요? 얼마전에 훌륭하게 Process 를 종료시킬 수 있는 방법을 구글링을 통해 발견해서 이야기해 봅니다. 특정 어플리케이션의 Process 를 확실히 죽이는 방법은 다음과 같습니다.
1.메니페스트 파일에 RESTART_PACKAGES 권한을 사용한다고 선언한다.
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>

2.ActivityManager 의 restartPackage API 를 호출한다.
ActivityManager am 
             = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
am.restartPackage(getPackageName());
 이전에는 System.exit() 나 Process.killProcess() 를 이용해서 Process 를 종료하려고 했습니다. 두 가지 방법 모두, Process 를 정상적으로 종료 시키는 듯 보일 때도 있었지만, 대게의 경우 어플리케이션 Process 가 죽었나... 하는 순간에 벌떡 하고 무덤에서 살아 돌아와 저를 우울하게 만들고 했습니다.

 어떠한 차이때문에 이런 일이 벌어지는 걸 까요? 안드로이드 Process의 생명 주기에 대해 다시 한번 확인해 봤습니다.  안드로이드 Application Fundamentals 에 명시되어 있는 내용은 다음과 같습니다. 

Android may decide to shut down a process at some point, when memory is low and required by other processes that are more immediately serving the user. Application components running in the process are consequently destroyed. A process is restarted for those components when there's again work for them to do.

 System.exit() 이나 Process.killProcess() 를 호출 하면, Process 가 강제로 종료되고, 안드로이드 플랫폼 입장에서는, 예기치않은 이유로 해당 Process 가 종료되었다고 판단하는 것으로 보입니다. 이 때, 해당 Process 가 해야할 일이 남아 있은 경우, 안드로이드 플랫폼 입장에서 이미 무덤에 돌아간 Process 를 다시 불러 일으키게 됩니다. 제가 알고있는 경우는 두 가지 입니다.
  •  START_NOT_STICKY 모드가 아닌 Service 가 작동 중인 경우.
  •  Activity Task 상에 현재 화면에 보이는 Activity 바로 아래 위치한 Activity 가 종료하고자 하는 Process 의 구성 요소 일 때. (Task 는 Process 가 아니라 안드로이드 시스템에서 관리하고 있음으로, 갑자기 종료된 Activity 바로 아래에 위치한 Activity 를 시스템에서 다시 시작하려고 함으로...) 
 그럼, restartPackage() 의 경우에는 어째서 Process 가 다시 살아나지 않는 것일까요? 그 답은 API 문서에 잘 나와 있습니다. 

public void restartPackage (String packageName)

Since: API Level 3

Have the system perform a force stop of everything associated with the given application package. All processes that share its uid will be killed, all services it has running stopped, all activities removed, etc. In addition, a ACTION_PACKAGE_RESTARTED broadcast will be sent, so that any of its registered alarms can be stopped, notifications removed, etc.


 API 설명에 잘 나와 있듯이, restartPackage() 의 경우, 단지 Process 를 종료하는 것이 아니라, 안드로이드 플랫폼에게 특정 어플리케이션 패키지가 종료됨을 알리고, 따라서 이미 실행중인 Service 나 Activity 를 안드로이드 시스템상에서 모두 제거하게 됩니다. 


<편히 잠들기를...>


 안드로이드 플랫폼은 우리가 알게 모르게 많은 일들을 수행하고 있습니다. 그렇기 때문에, 안드로이드 플랫폼에게 Process 가 죽었다는 사실을 알려준 후에야, 묻어놓은 개발자들은 시체가 무덤에서 다시 돌아오지 않을 것임을 확신하고 마음 편히 잠들 수 있습니다...






출처 : http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110082677696