Compose에서 화면을 전환하기 위해서는 Navaigation 사용이 필수적이다.
하지만 예전 버전의 경우 Route를 String으로 지정해줘야 하는 불편함이 있었다.
그런 불편함을 개선하고 새로 나온 Type Safety Navigation의 사용법과 주의점을 소개하고자 한다.
Dependencies
"androidx.navigation:navigation-compose:2.8.0-beta04" // 2.8.0-alpha01 부터 가능
"org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0" // kotlin 2.0
"org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" // kotlin 1.9.22
이렇게 두개를 필수로 설정해줘야 한다.
// build.gradle(project)
id("org.jetbrains.kotlin.plugin.serialization") version "1.5.31" apply false
// buildLogic(feature)
id("org.jetbrains.kotlin.plugin.serialization")
그래들에는 일반적으로 serialization을 쓸 때 처럼 설정해주면 된다.
How To Use?
fun NavController.navigateMy(navOptions: NavOptions) {
navigate(My, navOptions)
}
fun NavGraphBuilder.myNavGraph(navigateToDummy: () -> Unit) {
composable<My> {
MyRoute(navigateToDummy)
}
}
@Serializable
data object My : Route
이렇게 Serializable을 이용해서 Class를 Route로 사용할 수 있다.
그렇게 된다면 기존에 사용하던 것과 달리 String이 아닌, data Object 자체를 Route로 쓸 수 있다.
매개변수는 어떻게 전달할 수 있을까?
기존의 경우에는 경로에 String으로 넣어서 이동시켜야 하는 불편함이 있었다.
하지만 이번 버전부터는 아래처럼 함수에 매개변수를 넣는 것 처럼 이동할 수 있다
@Serializable
data class Profile(val id: String)
@Composable
fun ProfileScreen(
profile: Profile
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(text = "Profile")
Spacer(modifier = Modifier.height(8.dp))
Text(text = "id = ${profile.id}")
}
}
composable<Profile> { backStackEntry ->
val profile: Screen.Profile = backStackEntry.toRoute()
ProfileScreen(profile)
}
// Profile로 이동하는 경우
navController.navigate(Profile(id))
이렇게 대충 자동으로 된다
기존에 매개변수를 넣어주는 것 처럼 사용하면 된다.
사실 사용법은 이게 전부다. 아주 간단하고, 안전하게 navigation을 사용할 수 있다.
근데 뭔가 이상해요...
내 시간을 잡아먹은 친구다... with 14시간..🥲
2.7.7 버전을 쓸 때는 안나왔던 아래와 같은 에러가 갑자기 나오기 시작했다.
FrameEvents
updateAcquireFence: Did not find frame.
ImageReader_JNI
Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
찾아보니 "navigation 2.8.0-alpha01 ~ beta04"까지가 불안정해서 뜨는 오류였다.
즉, 라이브러리 자체적인 오류라 내가 해결이 불가능했다.
현재 버전의 오류로 탐색 지연이 일부 발생할 우려가 있다.
하지만 기존 네비게이션에 비해 너무나 편해졌기 때문에 에러문구를 무시하고 쓰려고 한다.
그래서 무시하는 방법을 찾아보고 적용했다.
1. 오류가 발생하는 코드 드래그
(오류가 발생하는 코드가 아닌 일반 코드다. 예시로 그냥 표기함)
2. 마우스 우클릭 후 Fold Lines Like This 클릭
3. OK 클릭
4. 완료.
더이상 해당 에러가 화면에 나오지 않을 것이다.
단, 실제로는 에러가 발생하고 있기 때문에 100% 해결된건 아니다.
빨리 해결된 Stable버전이 나오길….
위와같은 조치를 하고 잘 사용하던중 새로운 오류를 마주쳤다.
화면 이동간 매개변수로 Double 타입을 넣어주면 오류가 발생하고 앱이 종료된다.
하지만 Int, String, Float 등은 정상적으로 동작 되었기 때문에 Google IssueTracker에 제보하였다.
응답이 온 메일에서는 이미 노운 이슈라고 하고 해결중이라는 내용이 있었다.
그래서 결론적으로 현재는 Double타입을 매개변수로 넘기는 것은 불가능하다.
내가 겪은 상황에서는 Double을 Float로 변환하게되면 자리수가 바뀌면서 크리티컬한 에러가 발생했었다.
이를 해결하고자 Double -> String으로 변환을 시켜 Navigation으로 옮겨주고, 다시 String -> Double로 변환하여 사용하는 과정을 거쳤다.