본문 바로가기
Develop/Android

[Android] ProcessPhoenix 오픈소스 뜯어보기

by bona.com 2025. 2. 2.

안드로이드에서 앱을 재시작 해야 할 때 ProcessPhoenix를 사용하면 간편하게 프로세스를 종료하고 다시 앱을 실행할 수 있다.
나는 이러한 사실만 알고 있었고, 아래처럼 코드를 작성했을 때 문제가 없어 보였다.

Handler(Looper.getMainLooper()).post {
   Toast.makeText(context, TOKEN_EXPIRED_ERROR, Toast.LENGTH_LONG).show() // 토큰 만료 토스트 메세지
   ProcessPhoenix.triggerRebirth(context) // 앱 재실행 코드
}

 
위 코드는 토큰 만료 시 사용한 코드인데 
정작 토큰이 만료됐을 때 토스트 메세지만 뜨고 IllegalStateException이 발생하며 앱이 비정상 종료가 되어버린 것이다..

 
아래 글을 참고했을 때 category.DEFAULT를 추가해야 된다는 걸 보고 일시적으로 해결은 했다.
그러나 "왜??" 라는 의문이 들어 더 찾아보았다.
https://code.luasoftware.com/tutorials/android/how-to-restart-android-app-programmatically

 

How to Restart Android App Programmatically (ProcessPhoenix)

Use ProcessPhoenix library. ProcessPhoenix.triggerRebirth(context); Ensure AndroidManifest.xml has the entry , else you might bump into the following exception java.lang.IllegalStateException: Unable to determine default activity for com.luasoftware.luapas

code.luasoftware.com

 

ProcessPhoenix

우선 ProcessPhoenix는 Jake Wharton분이 작성한 오픈소스이다. 
https://github.com/JakeWharton/ProcessPhoenix

 

GitHub - JakeWharton/ProcessPhoenix: Process Phoenix facilitates restarting your application process.

Process Phoenix facilitates restarting your application process. - JakeWharton/ProcessPhoenix

github.com

 
ProcessPhoenix.java 파일을 보면 triggerRebirth() 함수를 호출하는 방법은 여러 가지이다.
별다른 Intent 없이 호출할 수도 있고, 직접 원하는 Intent를 넘겨서 호출할 수도 있다.
 
나는 아래 코드처럼 Intent 없이 호출했으므로 이렇게 했을 때의 흐름으로 파악해보자.

 ProcessPhoenix.triggerRebirth(context)

 

ProcessPhoenix.java 파일

Java 언어를 잘 아는 사람이라면 첫 번째 triggerRebirth() 함수가 호출될 것이란 걸 알 수 있을 것이다.
그리고 다시 triggerRebirth() 함수를 호출하면서 내부적으로 getRestartIntent() 함수를 실행하고 있다.

 

ProcessPhoenix.java 파일

이제 getRestartIntent() 함수를 보자.
 
이 함수의 목적은 사용자가 액티비티를 별도로 지정하지 않았을 때(나와 같은 경우) 기본 런처 액티비티를 찾기 위함이다.
그래서 이때 매니페스트에 intent-filter가 제대로 설정되어 있지 않다면 defaultIntent = null이 되며 예외를 발생시키고 있다.
Jake Wharton분이 작성한 예외와 내가 발생한 예외가 동일한 것을 확인할 수 있다..
 
이제 이 예외를 해결했으므로 여기서 문제가 없다고 가정하고 넘어가보자.

ProcessPhoenix.java 파일

그럼 이 triggerRebirth() 함수로 오게 된다.
 
이 함수의 목적은 PhoenixActivity를 실행해 현재의 프로세스를 없애고, 새 프로세스에서 실행할 nextIntents를 넘겨주는 것이다.
그래서 nextIntents에 아래처럼 기존의 테스크를 모두 비워주고 있다.

nextIntents[0].addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);

 
그 다음 내부적으로 intent를 하나 만들어서 PhoenixActivity를 실행하고자 한다.

Intent intent = new Intent(context, PhoenixActivity.class);
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);

 
그리고 이 intent에 새로 실행할 nextIntents와 현재의 프로세스를 담아, startActivity를 통해 PhoenixActivity를 실행한다.

intent.putParcelableArrayListExtra(
KEY_RESTART_INTENTS, new ArrayList<>(Arrays.asList(nextIntents)));
intent.putExtra(KEY_MAIN_PROCESS_PID, Process.myPid());

context.startActivity(intent);

 

PhoenixActivity.java 파일

마지막으로 PhoenixActivity이다.
기존의 프로세스는 killProcess() 함수를 통해 없애고, getIntent() 함수로 새로 실행할 인텐트 배열을 꺼내고 있다.
 
이제 새로 실행할 인텐트를 실행해 준다.

 startActivities(intents);

 
동시에 현재 액티비티도 즉시 종료해 준다.
(주석에 kill을 3번이나 달으셨다..😮)

finish();
Runtime.getRuntime().exit(0);

 

그러면 모든 과정이 성공적으로 진행된 것이다!

 

마치며

그동안 별 생각 없이 쓰던 코드를 하나하나 뜯어보니 프로세스가 어떻게 생성되고 소멸되는지 파악하는 것도 재밌었고, 오픈소스 코드에 대한 두려움도 없어진 것 같다!
 
코드를 작성할 때 한 줄이라도 이유 있는 코드를 작성하고 싶다는 마음에서 시작된 오픈소스 뜯어보기인데 스스로 만족스럽다.
 
마지막으로 이러한 과정을 해결한 PR도 같이 남기겠다.
https://github.com/teamterning/Terning-Android/pull/337

 

[FIX/#336] 토큰 만료 시 IllegalStateException 해결 by leeeyubin · Pull Request #337 · teamterning/Terning-Android

closed [FIX] 토큰 만료 시 IllegalStateException 해결 #336 ⛳️ Work Description DEFAULT intent filter 추가 버전 코드 업데이트 1.2.0 -> 1.2.1 📸 Screenshot 📢 To Reviewers 문제 상황: 토큰 만료 시 ProcessPhoenix를 이용하

github.com