들어가며...
앱을 만들다보면 강제로 재실행을 해야하는 순간들이 몇 있다.
본인의 경우, 다국어를 지원하는 앱에서 언어 변경사항을 모든 액티비티와 프래그먼트에 적용해, 자동으로 로드 될 수 있도록 하기 위한 조치였다.
앱을 강제로 재실행 시키기
[코드]
fun restartApp(context: Context) {
val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
context.startActivity(intent)
Runtime.getRuntime().exit(0)
}
}
[사용예시]
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.button.setOnClickListener {
// ✅ 버튼을 누르면 앱 재실행
restartApp(this@MainActivity)
}
}
정확하게는 앱의 최상위 액티비티를 재시작하는 코드다.
간략한 설명을 함께 기록한다.
1. PackageManager
및 ComponentName
변수를 사용하는 대신에 Intent
를 직접 사용한다.
PackageManager를 사용해 현재 앱의 launch intent를 가져온 후, 해당 인텐트의 컴포넌트를 얻는 방식을 쉽게 접할 수 있다.
위 코드처럼, getLaunchIntentForPackage() 메서드를 직접 호출해서 런치 인텐트를 얻을 수 있고, 이렇게 하면 불필요한 변수 할당을 줄일 수 있다.
2. addFlag()
로 액티비티를 재시작하는 데 필요한 플래그를 추가 직접 사용
인텐트에 플래그를 직접 추가하는 방법은 간단하면서도 호환성아, API 레벨을 크게 고려하지 않아도 된다.
위 코드에서는 FLAG_ACTIVITY_CLEAR_TOP
과 FLAG_ACTIVITY_NEW_TASK
플래그를 추가하여 액티비티를 재시작한다.
해당 플래그들의 기능은 다음과 같다.
FLAG_ACTIVITY_CLEAR_TOP
: 스택에 있는 모든 액티비티를 제거하고, 해당 액티비티 위에 새로운 인스턴스를 생성한다.FLAG_ACTIVITY_NEW_TASK
: 새로운 Task에서 액티비티를 시작한다.
3. getLaunchIntentForPackage()
반환값의 'null' 여부를 검사하여 앱 시작 인텐트의 유효성을 확보한다.
getLaunchIntentForPackage()
는 해당 패키지의 런치 인텐트를 반환한다.
그런데, 시스템이 이 패키지에 대한 런치 인텐트를 찾지 못한 경우(주로 패키지 이름이 잘못된 경우) null이 반환된다.
따라서 반환된 인텐트의 null체크를 통해 유효성을 검사하고, 유효한 경우에만 액티비티를 재시작하도록 한다.
Compose에서는 context 부분에 Localcontext.current as compose
가 있는 액티비티(ex. MainActivity)를 넘겨주면 된다.
'Android > 개인 기록' 카테고리의 다른 글
[Compose] Custom CameraView 만들기 (0) | 2024.03.29 |
---|---|
[Android Tip] Immortal Service (죽지 않는 서비스) (2) | 2023.09.29 |
[Android: Basic] GPS Location Service (위치정보 서비스) (0) | 2023.05.23 |
Permission Check (권한 요청) (0) | 2023.04.07 |
[Android] ignoring header x-firebase-locale because its value was null과 Realtime Database 사용이 안되는 오류 해결 (0) | 2022.12.31 |