Uing? Uing!!

[안드로이드 삽질기록] Compose와 안드로이드 13의 예측 뒤로가기 기능을 같이 사용하면 물리 뒤로가기 키가 고장나는 버그가 있다 본문

Android

[안드로이드 삽질기록] Compose와 안드로이드 13의 예측 뒤로가기 기능을 같이 사용하면 물리 뒤로가기 키가 고장나는 버그가 있다

Uing!! 2023. 9. 9. 23:46
반응형

발단

요즈음 Compose를 도입하고 있는데, 앱에 그동안 안드로이드 뷰로만 사용하던 드랍다운 메뉴를 컴포즈로 새롭게 구현해 넣을 일이 생겼다.
아래는 문제가 되었던 DropDownMenu 구현의 예시이다.
(실제 사용한 코드와는 다른데,  글의 가독성을 위해 최대한 단순화시켰다)

@Composable
fun DropdownMenuExample() {
    Box(modifier = Modifier.fillMaxWidth().wrapContentSize(Alignment.TopEnd)) {
        var popupVisible by remember { mutableStateOf(false) }
        IconButton(onClick = { popupVisible = popupVisible.not() }) {
            Icon(imageVector = Icons.Default.MoreVert, contentDescription = "")
        }
        DropdownMenu(
            onDismissRequest = { popupVisible = false },
            expanded = popupVisible,
        ) {
            DropdownMenuItem(
                text = { Text("Menu 1") },
                onClick = {}
            )
            DropdownMenuItem(
                text = { Text("Menu 2") },
                onClick = {}
            )
        }
    }
}

기본적으로 메뉴는 잘 동작했다. 그런데, 이 팝업 메뉴가 뒤로가기 버튼을 아무리 눌러도 닫히지 않는 것이었다. 특별히 이상하게 한 것은 없는 것 같았는데 당황스러웠다.
정말 희한한 것은 똑같은 코드를 복사-붙여넣기 하여 새로운 샘플 앺에서 동작시키면 정상적으로 뒤로가기 시 닫힘 동작을 한다는 것이었다.

삽질

1) 안드로이드 13(api 33)에서 발생하는 것을 확인

처음 이 문제가 발견된 것은 안드로이드 13(api 33) 실기기였다. 픽셀 api 33 에뮬레이터에서도 동일했는데, 안드로이드 32 에뮬레이터에서는 발생하지 않았다. 안드로이드 13 에서만 발생하는 버그임을 확인했다.


2) 정상 동작하는 샘플 앱을 만들어 차이를 확인

웬만하면 내 잘못일 것이라고 생각하여, 정상 동작하는 최대한 간단한 샘플 앱을 만들고 비교해보기로 했다.
확인을 위해서 앞서 말했듯 새로운 샘플 앱 빈 페이지에 동일한 드랍다운 메뉴를 달아 동작시켜 보았는데, 샘플 앱에서는 잘 동작했다.
그 다음으로는 혹시 드랍다운을 사용하는 화면에 문제가 있는가 싶어서 원래 구현중이던 앱의 스플래시 화면을 빈 화면으로 바꿔 샘플앱과 동일하게 만들어 보았는데, 앱 시작 후 해당 화면까지의 모든 것이 동일함에도 샘플 앱과 다르게 뒤로가기가 먹지 않았다.
테스트 결과 메뉴와 화면을 구현한 방식에서 별다른 문제가 있어 보이지는 않았다.

 

그러면 어떤 차이가 있나 하고 backpress 관련된 내용을 여기저기 최대한 살펴 보다가, AndroidManifest에서 아래와 같은 부분을 발견했다.

<application
    android:enableOnBackInvokedCallback="true"
    ...

혹시...? 하고 enableOnBackInvokedCallback=true 부분을 제거하고 동작시켜 보았다.

뒤로가기가 정상 동작했다.

 

3) enableOnBackInvokedCallback가 문제가 맞는지 서칭

enableOnBackPressInvokedCallback라는 키워드를 얻고 다시 이슈트래커에서 서칭을 하자, 아래와 같은 버그 제보들을 찾을 수 있었다.
https://issuetracker.google.com/issues/285847710
https://issuetracker.google.com/issues/281967264
https://issuetracker.google.com/issues/271303558


증상은 모두 동일했고, DropDownMenu, BottomSheetMenu와 같은 Popup 형식의 뷰를 사용하고 있다는 공통점이 있었다.

 

4) 버그를 무시하고 정상동작 시킬 방법 모색

버그를 확인한 이후 직접 BackHandler를 다는 방식, focusable을 끄고 동작시키는 방법 등 몇가지 방법을 시도해 보았지만 모두 실패했다. 정확히는, 뒤로가기 물리키 자체는 성공하는 경우도 있었지만, 그 외 다른 곳에서 사이드 이펙트들이 발생하여 모두 정상적으로 사용할 수 없는 방법들이었다.

물론 이것보다 더 복잡한 방법을 사용해 어떻게든 동작시킬 방법이 있기는 했겠지만, 지나친 커스텀은 레거시를 만드는 지름길이라고 생각하여 배제하였다.

 

5) enableOnBackInvokedCallback 옵션 해제
결국 아쉬운 마음을 뒤로 하고 예측 뒤로가기 기능을 당분간 포기하기로 결정하며 짧은 주석과 함께 매니페스트 코드를 아래와 같이 수정했다.

<application
    ... // enableOnBackInvokedCallback 부분 제거

뒤로가기 버튼은 바로 정상 동작하기 시작했다.

결론

Compose에서  DropDownMenu, BottomSheetMenu, 또는 Popup 그 자체와 깉은 팝업류 뷰를 사용할 때, 매니페스트에 예측 뒤로가기를 위한  enableOnBackPressInvokedCallback 옵션이 켜져 있으면 안드로이드 13(api 33)에서는 뒤로가기 키가 먹히지 않는 버그가 존재한다.

따라서 앱에 컴포즈가 사용되고 있거나 도입하는 중이라면, 추후 업데이트 전까지는 예측 뒤로가기 기능이 맛있어 보이더라도 enableOnBackPressInvokedCallback 옵션을 꺼 두는 것을 보류하는 것이 좋다.

 

 

반응형
Comments