Проблема с удалением метки (RuntimeException: Failed to remove MapObject)
DemaFay opened this issue · 1 comments
Использую MapView внутри фрагмента.
Версия используемого mapkit 4.3.2-lite
Методы showMarkers и updateMarker вызываются в Main потоке
class MapFragment : BaseFragment(), ClusterListener, ClusterTapListener, MapObjectTapListener, CameraListener {
private var pointsCollection: ClusterizedPlacemarkCollection? = null
private val placemarksOnMap = mutableListOf<PlacemarkMapObject>() //Это список с добавленными маркерами в карту.
//1) В методе onCreate произвожу инициализацию MapKitFactory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
MapKitFactory.initialize(requireContext())
viewModel = DI.provideViewModel(this)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentTaskMapBinding.inflate(inflater, container, false)
binding.mvMap.map.addCameraListener(this)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.getViewState()
.observeWith(this) { signal -> //2 тут обрабатываю события. (Показать точки на карте)
when(signal) {
is TaskMapViewModel.ViewSignal.ShowMarkers -> {
showMarkers(signal.markers)
}
is TaskMapViewModel.ViewSignal.UpdateMarker -> { //3 Обновить(Удалить и отобразить снова) точку по его ID
updateMarker(signal.marker)
}
}
}
viewModel.getCameraState()
.observeWith(this) { signal ->
setupCameraPosition(signal.cameraPosition)
}
viewModel.onViewCreated()
}
//4 Тут все работает нормально. Маркеры отображаются на карте.
private fun showMarkers(markers: List<TaskMarkerData>) {
binding.mvMap.map.mapObjects.clear() //Очищаю все метки
placemarksOnMap.clear() //Очищаю список Placemark-ов, которые были добавлены в карту.
pointsCollection = binding.mvMap.map.mapObjects.addClusterizedPlacemarkCollection(this)
markers.forEach { marker ->
placemarksOnMap.add(addMarker(pointsCollection!!, marker)) //Метод addMarker добавляет маркер в карту, при добавлении новой метки создается PlacemarkMapObject которую возвращает метод addMarker и сохраняет его в списке placemarksOnMap
}
pointsCollection?.clusterPlacemarks(20.0, Int.MAX_VALUE)
}
//5 Тут процесс обновления маркера на карте
private fun updateMarker(marker: TaskMarkerData) {
placemarksOnMap.find { it.getPointMarker()?.pointId == marker.pointId }?.let { markerToRemove -> //тут мы находим MapObject по ID который был добавлен на карту.
binding.mvMap.map.mapObjects.remove(markerToRemove) //Тут пытаемся удалить и происходит краш.
//Так же в интернете был дан немного другой способ для удаления точки.
//binding.mvMap.map.mapObjects.parent.remove(markerToRemove) //Данный способ так же не работает, в моем случай mapObjects.parent == null
}
pointsCollection?.let { points ->
addMarker(points, marker)
}
}
override fun onStart() {
MapKitFactory.getInstance().onStart()
binding.mvMap.onStart()
viewModel.onStart()
super.onStart()
}
override fun onStop() {
MapKitFactory.getInstance().onStop()
binding.mvMap.onStop()
super.onStop()
}
private fun addMarker(
pointsCollection: ClusterizedPlacemarkCollection,
marker: TaskMarkerData
): PlacemarkMapObject {
val bitmap = placemarkBitmapFactory.create(marker)
val bitmapProvider = ImageProvider.fromBitmap(bitmap)
val iconStyle = IconStyle()
.setAnchor(placemarkBitmapFactory.getAnchorPoint(bitmap))
.setFlat(false)
.setVisible(true)
return pointsCollection.addPlacemark(
marker.location.toPoint(),
bitmapProvider, iconStyle
).also { placemark ->
placemark.userData = marker
placemark.addTapListener(this)
placemark.setupZIndex()
}
}
}
Лог с ошибкой:
FATAL EXCEPTION: main
Process: ru.mvideo.lastmile.debug, PID: 27174
java.lang.RuntimeException: Failed to remove MapObject
Exception stack trace (top 8 entries):
# 0: 7905420 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so
# 1: 7937112 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so
# 2: 7936948 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so
# 3: 7933792 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so
# 4: 7933592 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so
# 5: 7936128 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so
# 6: 13984180 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so
# 7: 13371316 /data/app/ru.mvideo.lastmile.debug-v9Bf3eSKfLi_T5g_BzEgjA==/base.apk!/lib/arm64-v8a/libmaps-mobile.so Java_com_yandex_mapkit_map_internal_BaseMapObjectCollectionBinding_remove__Lcom_yandex_mapkit_map_MapObject_2
at com.yandex.mapkit.map.internal.BaseMapObjectCollectionBinding.remove(Native Method)
at ru.mvideo.lastmile.ui.screen.tasks.mapv2.TaskMapFragment.updateMarker(TaskMapFragment.kt:147)
at ru.mvideo.lastmile.ui.screen.tasks.mapv2.TaskMapFragment.access$updateMarker(TaskMapFragment.kt:29)
at ru.mvideo.lastmile.ui.screen.tasks.mapv2.TaskMapFragment$onViewCreated$1.invoke(TaskMapFragment.kt:86)
at ru.mvideo.lastmile.ui.screen.tasks.mapv2.TaskMapFragment$onViewCreated$1.invoke(TaskMapFragment.kt:77)
at ru.mvideo.lastmile.util.ui.vm.LiveDataExtensionsKt.observeWith$lambda$0(LiveDataExtensions.kt:13)
at ru.mvideo.lastmile.util.ui.vm.LiveDataExtensionsKt.$r8$lambda$n8EX_c4Nl9gbhRgAGPKyFyQ_NpY(Unknown Source:0)
at ru.mvideo.lastmile.util.ui.vm.LiveDataExtensionsKt$$ExternalSyntheticLambda0.onChanged(Unknown Source:2)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at androidx.lifecycle.LiveData$1.run(LiveData.java:93)
at android.os.Handler.handleCallback(Handler.java:794)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:6635)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Я подробно изучил уже созданные issues связанный с подобной ошибкой RuntimeException: Failed to remove MapObject
Например: #81
В данной ситуации проблема решена object.getParent().remove(object);
В моем случай object.getParent() == null
Так же изучил: #73
cdump commented [on Mar 3, 2019](#73 (comment)
В моем случай вылет происходит вне зависимости вызова метода onDestroy, то есть краш срабатывает всегда, (На этапе работы с приложением родительский фрагмент не закрывается, приложение не сворачивается, не закрывается, и тд.)
Вы добавляете плейсмарки в одну коллекцию, а удаляете их из другой. Это приводит к ошибке.