Android Jetpack Compose Kakao Map Init Error

@HiltAndroidApp
class ExpoApplication : Application() {

    @Inject
    @Named("NATIVE_APP_KEY")
    lateinit var nativeAppKey: String

    override fun onCreate() {
        super.onCreate()

        KakaoMapSdk.init(this, nativeAppKey) // 카카오맵 초기화 코드 및 nativeAppKey(local.properties에 저장된 값 사용)
    }
}
// Application
@Module
@InstallIn(SingletonComponent::class)
object AppConfigModule {

    @Provides
    @Named("NATIVE_APP_KEY")
    fun provideNativeAppKey(): String = BuildConfig.NATIVE_APP_KEY
}
// hilt 의존성 연결을 하기위한 코드



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:name=".ExpoApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.App.Starting"
        tools:targetApi="31">

        <meta-data
            android:name="com.kakao.sdk.AppKey"
            android:value="@string/navigation_app_key" />

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:theme="@style/Theme.App.Starting">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
// Android App Module Manifest File
@Composable
internal fun HomeKakaoMap(
    modifier: Modifier = Modifier,
    locationX: Double, // 서버에서 제공하는 X 값 (경도)
    locationY: Double, // 서버에서 제공하는 Y 값 (위도)
) {
    val context = LocalContext.current
    val mapView = remember { MapView(context) }

    AndroidView(
        modifier = modifier.height(200.dp), // AndroidView의 높이 임의 설정
        factory = { context ->
            mapView.apply {
                mapView.start(
                    object : MapLifeCycleCallback() {
                        // 지도 생명 주기 콜백: 지도가 파괴될 때 호출
                        override fun onMapDestroy() {
                            // 필자가 직접 만든 Toast생성 함수
                            makeToast(context = context, toastMessage = "지도를 불러오는데 실패하였습니다")
                        }

                        // 지도 생명 주기 콜백: 지도 로딩 중 에러가 발생했을 때 호출
                        override fun onMapError(exception: Exception?) {
                            // 필자가 직접 만든 Toast생성 함수
                            makeToast(context = context, toastMessage = "지도를 불러오는 중 알 수 없는 에러가 발생했습니다.\n onMapError: $exception")
                        }
                    },
                    object : KakaoMapReadyCallback() {
                        // KakaoMap이 준비되었을 때 호출
                        override fun onMapReady(kakaoMap: KakaoMap) {
                            // 카메라를 (locationY, locationX) 위치로 이동시키는 업데이트 생성
                            val cameraUpdate = CameraUpdateFactory.newCenterPosition(LatLng.from(locationY, locationX))

                            // 지도에 표시할 라벨의 스타일 설정
                            val style = kakaoMap.labelManager?.addLabelStyles(LabelStyles.from(LabelStyle.from(R.string.location_icon_description)))

                            // 라벨 옵션을 설정하고 위치와 스타일을 적용
                            val options = LabelOptions.from(LatLng.from(locationY, locationX)).setStyles(style)

                            // KakaoMap의 labelManager에서 레이어를 가져옴
                            val layer = kakaoMap.labelManager?.layer

                            // 카메라를 지정된 위치로 이동
                            kakaoMap.moveCamera(cameraUpdate)

                            // 지도에 라벨을 추가
                            layer?.addLabel(options)
                        }

                        override fun getPosition(): LatLng {
                            // 현재 위치를 반환
                            return LatLng.from(locationY, locationX)
                        }
                    },
                )
            }
        },
    )
}
// Kakao MapView

이러한 형태로 KakaoMap 구현을 하였는데 init이 잘 되어있는 거 같은데 앱을 확인하려고 돌려보면

java.lang.RuntimeException: KakaoMapSdk is not initialized. (Ask Gemini)
                                                                                                    	at com.kakao.vectormap.MapView.checkKakaoMapSdk(MapView.java:254)
                                                                                                    	at com.kakao.vectormap.MapView.start(MapView.java:55)
                                                                                                    	at com.school_of_company.home.component.HomeKakaoMapComponentKt$HomeKakaoMap$1.invoke(HomeKakaoMapComponent.kt:36)
                                                                                                    	at com.school_of_company.home.component.HomeKakaoMapComponentKt$HomeKakaoMap$1.invoke(HomeKakaoMapComponent.kt:32)
                                                                                                    	at androidx.compose.ui.viewinterop.ViewFactoryHolder.<init>(AndroidView.android.kt:344)
                                                                                                    	at androidx.compose.ui.viewinterop.AndroidView_androidKt$createAndroidViewNodeFactory$1$1.invoke(AndroidView.android.kt:275)
                                                                                                    	at androidx.compose.ui.viewinterop.AndroidView_androidKt$createAndroidViewNodeFactory$1$1.invoke(AndroidView.android.kt:274)
                                                                                                    	at androidx.compose.runtime.changelist.Operation$InsertNodeFixup.execute(Operation.kt:585)
                                                                                                    	at androidx.compose.runtime.changelist.Operations.executeAndFlushAllPendingOperations(Operations.kt:310)
                                                                                                    	at androidx.compose.runtime.changelist.FixupList.executeAndFlushAllPendingFixups(FixupList.kt:50)
                                                                                                    	at androidx.compose.runtime.changelist.Operation$InsertSlotsWithFixups.execute(Operation.kt:552)
                                                                                                    	at androidx.compose.runtime.changelist.Operations.executeAndFlushAllPendingOperations(Operations.kt:310)
                                                                                                    	at androidx.compose.runtime.changelist.ChangeList.executeAndFlushAllPendingChanges(ChangeList.kt:81)
                                                                                                    	at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:984)
                                                                                                    	at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1013)
                                                                                                    	at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1150)
                                                                                                    	at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:649)
                                                                                                    	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:635)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:133)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:124)
                                                                                                    	at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1626)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:124)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:180)
                                                                                                    	at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.jvm.kt:320)
                                                                                                    	at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.jvm.kt:198)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:124)
                                                                                                    	at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:1707)
                                                                                                    	at android.view.View.dispatchAttachedToWindow(View.java:22889)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3504)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3504)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3504)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3504)
                                                                                                    	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3373)
                                                                                                    	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2847)
                                                                                                    	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10190)
                                                                                                    	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1406)
                                                                                                    	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1415)
                                                                                                    	at android.view.Choreographer.doCallbacks(Choreographer.java:1015)
                                                                                                    	at android.view.Choreographer.doFrame(Choreographer.java:945)
                                                                                                    	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1389)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:959)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:100)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:232)
                                                                                                    	at android.os.Looper.loop(Looper.java:317)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8699)
2024-11-05 08:23:37.640 12432-12432 K3fAApi                 com.school_of_company.home.test      E  	at java.lang.reflect.Method.invoke(Native Method) (Ask Gemini)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)

위와 같은 init 에러가 나옵니다…

어떤게 문제인지 알려주실분있나요??

위의 에러는 KakaoMapSdk 클래스의 객체가 null 일 때 나오는 에러입니다.

  1. KakaoMapSdk.init() 함수 호출이 MapView.start() 호출보다 먼저 실행됐는지 확인해주시고,
  2. MapView.start() 호출하기 직전에도 앱 구현 상황에 의해 KakaoMapSdk.INSTANCE 가 null이 된건 아닌지 확인 부탁 드립니다.

해결완료했습니다!
답변감사합니다!