androidkotlinlayout-inflateryandex-apiyandex-mapkit

Yandex MapKit Inflation crash


I am trying to implement Yandex MapKit in my app, but unfortunately it crashes immediately with the following error:

2022-06-07 15:05:48.838 23491-23491/sbs.pros.parking E/AndroidRuntime: FATAL EXCEPTION: main
Process: sbs.pros.parking, PID: 23491
java.lang.RuntimeException: Unable to start activity ComponentInfo{sbs.pros.parking/sbs.pros.parking.MainActivity}: android.view.InflateException: Binary XML file line #6 in sbs.pros.parking:layout/activity_main: Binary XML file line #6 in sbs.pros.parking:layout/activity_main: Error inflating class com.yandex.mapkit.mapview.MapView
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4035)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4201)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
 Caused by: android.view.InflateException: Binary XML file line #6 in sbs.pros.parking:layout/activity_main: Binary XML file line #6 in sbs.pros.parking:layout/activity_main: Error inflating class com.yandex.mapkit.mapview.MapView
 Caused by: android.view.InflateException: Binary XML file line #6 in sbs.pros.parking:layout/activity_main: Error inflating class com.yandex.mapkit.mapview.MapView
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
    at android.view.LayoutInflater.createView(LayoutInflater.java:858)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1010)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:965)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:1127)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:686)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:538)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:485)
    at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:533)
    at android.app.Activity.setContentView(Activity.java:3589)
    at sbs.pros.parking.MainActivity.onCreate(MainActivity.kt:43)
    at android.app.Activity.performCreate(Activity.java:8290)
    at android.app.Activity.performCreate(Activity.java:8270)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4009)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4201)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
 Caused by: java.lang.AssertionError: You need to set the API key before using MapKit!
    at com.yandex.mapkit.MapKitFactory.checkApiKey(MapKitFactory.java:64)
    at com.yandex.mapkit.MapKitFactory.initialize(MapKitFactory.java:24)
2022-06-07 15:05:48.838 23491-23491/sbs.pros.parking E/AndroidRuntime:     at com.yandex.mapkit.mapview.MapView.<init>(MapView.java:53)
    at com.yandex.mapkit.mapview.MapView.<init>(MapView.java:46)
        ... 29 more

When I swap lines setContentView(R.layout.activity_main) and MapKitFactory.initialize(this), the error changes to smth like "you must set up api key first before initializing". In any case, the issue probably appeared because the api key is not set up properly, though I included it in Application activity (when it was included in onCreate method, the same error remains):

import android.app.Application
import android.util.Log
import com.yandex.mapkit.MapKitFactory

class MyApp : Application() {
private val MAPKIT_API_KEY = "<my actual api key>"
override fun onCreate() {
    super.onCreate()
    Log.w("MY", "onCreate MyApp")
    MapKitFactory.setApiKey(MAPKIT_API_KEY)
}
}

MainActivity.kt:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.yandex.mapkit.Animation
import com.yandex.mapkit.MapKitFactory
import com.yandex.mapkit.geometry.Point
import com.yandex.mapkit.map.CameraPosition
import com.yandex.mapkit.mapview.MapView


class MainActivity : AppCompatActivity() {

private val TARGET_LOCATION = Point(59.945933, 30.320045)
private val mapView: MapView? = null
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.activity_main)

    MapKitFactory.initialize(this)

    val mapView = findViewById<MapView>(R.id.mapview)
    mapView.map.move(
        CameraPosition(TARGET_LOCATION, 11.0f, 0.0f, 0.0f),
        Animation(Animation.Type.SMOOTH, 0F),
        null
    )
}
override fun onStop() {
    mapView?.onStop()
    MapKitFactory.getInstance().onStop()
    super.onStop()
}

override fun onStart() {
    super.onStart()
    MapKitFactory.getInstance().onStart()
    mapView?.onStart()
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout             
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.yandex.mapkit.mapview.MapView
    android:id="@+id/mapview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
</RelativeLayout>

Does anybody have an idea how to fix this?


Solution

  • You're getting that error you're talking about anyway:

    Caused by: java.lang.AssertionError: You need to set the API key before using MapKit!
    

    At a guess, it's because you're calling setContentView (which inflates the layout and initialises the widget) before you call MapKitFactory.initialize(this). The documentation's example initialises it first:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        MapKitFactory.initialize(this)
        setContentView(R.layout.activity_main)