Android/다양한 기능들(Library)

[Android] Type Safety Navigation With Compose

chattymin 2024. 6. 28. 14:23
728x90
반응형

 

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버전이 나오길….

728x90
반응형