회사에서 진행하는 프로젝트 요구 사항 중 특정 화면에서 앱이 백그라운드로 진입하면 앱을 종료시키는 상황이 있었다.
고민이 많았다.
매우 단순히 Activity가 onStop될 때, 꺼버리자! 라는 생각을 했는데 당연하게도 아주 우매한 생각이었다.
왜냐하면, 예를 들어 메인 페이지에서 설정 화면으로 이동할 때 onStop이 호출되고 그냥 앱이 종료되었다.
(이것도 생각못하냐고 하면 뭐... 할 말이 없다)
그럼 어떻게 할까 일단 앱이 백그라운드로 진입할 때 무조건 onDestroy까지 호출될 수는 없었다.
여러 고민을 거쳐 결국 라이프사이클을 사용해 구현해냈다.
1. 먼저, 모듈 수준의 build.gradle에서 라이브러리를 추가해주어야 한다.
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.0'
implementation 'androidx.lifecycle:lifecycle-process:2.6.0'
나는 코틀린으로 작성해 ktx가 붙어있고, 버전은 내가 작성한 날짜 기준으로 최신 버전이다.
2. 그리고 Application을 상속한 MainApplication 클래스를 만들었다.
이 때, DefaultLifecycleObserver와 ActivityLifecycleCallbacks를 implements 해주어야 한다.
먼저, DefaultLifecycleObserver는 MainApplication의 lifecycle을 감지한다.
그리고 ActivityLifecycleCallbacks는 이름 그대로 액티비티의 lifecycle을 감지한다.
일단 아래 전체 코드를 보면서 설명해보겠다.
import android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import kotlin.system.exitProcess
class MainApplication: Application(), DefaultLifecycleObserver, ActivityLifecycleCallbacks {
lateinit var activityName: String
lateinit var activity: Activity
override fun onCreate() {
super<Application>.onCreate()
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
registerActivityLifecycleCallbacks(this)
}
override fun onStop(owner: LifecycleOwner) {
super.onStop(owner)
when (activityName) {
"MainActivity" -> {
activity.finishAffinity()
exitProcess(0)
}
"SettingActivity" -> {
activity.finishAffinity()
exitProcess(0)
}
}
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
}
override fun onActivityStarted(activity: Activity) {
}
override fun onActivityResumed(activity: Activity) {
activityName = activity.javaClass.simpleName
this.activity = activity
}
override fun onActivityPaused(activity: Activity) {
}
override fun onActivityStopped(activity: Activity) {
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
}
override fun onActivityDestroyed(activity: Activity) {
}
}
액티비티 onResume에서 해당 액티비티 이름을 가져온다.
그리고 Application이 onStop이 되었을 때,
가져온 activity의 이름을 가지고 when을 통해 이름을 비교하고 앱을 종료시킨다.
나는 왜 이런 코드를 짰을까?
첫 번째 시도) 단순히 Application을 상속받은 클래스를 만들어 Application이 onStop되면 앱을 종료시키려 했었다.
당연히 실패했다.
왜냐하면, 모든 화면에서 백그라운드를 진입했을 때 앱이 종료되었기 때문이다. (어찌보면 당연..)
두 번째 시도) 그럼 특정 액티비티에서 onStop될 때, Application이 onStop되는 걸 보고 종료시키자!
멍청한 생각이었다.
왜냐하면, 액티비티의 onStop이 호출되고 Application의 onStop이 호출되기 때문에
액티비티에서는 Application의 onStop을 감지할 수 없었다.
세 번째 시도) 아오.. 그럼 Application에서 특정 액티비티가 onStop되는 걸보고 종료시켜보자.
아니... 근데 Application이 어떤 액티비티가 실행되고 있는지 어떻게 알까? -> 이것 때문에 엄청 검색을 했다.
그렇게 완성된 기능이 바로 위의 코드이다.
'Android' 카테고리의 다른 글
종종 간과하는 문제 해결 에피소드(feat. Handler, Thread) (0) | 2023.04.24 |
---|---|
구글 플레이 개발자 이름 주의 사항(오늘도 여전한 구글) (0) | 2023.03.27 |
Android Studio Waiting For Debugger 현상 해결 (0) | 2023.03.07 |
안드로이드 스튜디오와 Gradle 버전의 호환성 이슈 (0) | 2023.02.28 |
기존 프로젝트의 Java to Kotlin 전환 시 주의점 (0) | 2023.02.26 |