Closed DazzlingFame closed 2 years ago
+1, аналогичная проблема на Android. Под IOS такого не происходит.
Мб связано вот с этим issue https://github.com/yandex/mapkit-android-demo/issues/73
Мб связано вот с этим issue yandex/mapkit-android-demo#73
Уже натыкался на это и судя по ошибке, частично это оно и есть, но вот что с этим делать...
Также есть олд ишью, где парень радикально решил проблему просто отключив child
у Marker
:(
UPD: костыль - зачищать стейт из которого рисуются метки, пока что лучше ничего не придумал.
Думаю в этой функции нужно добавить проверок на null, чтобы исправить проблему. Возможно есть какая-то функция isValid, для объектов MapKit. Постараемся проверить этот блок и исправить проблему. Есть ли фрагмент кода, на котором проблема воспроизводится стабильно?
Думаю в этой функции нужно добавить проверок на null, чтобы исправить проблему. Возможно есть какая-то функция isValid, для объектов MapKit. Постараемся проверить этот блок и исправить проблему. Есть ли фрагмент кода, на котором проблема воспроизводится стабильно?
Проверку на isValid()
добавил и это теперь исправило вылет, но мне кажется что просто сброс апдейта это как то "жестко". Может быть надо если не валидный объект - удалять его как то?
Тут суть в том что он пытается обновить маркер который уже удален, потому что его children тоже удалился. Дальше обновлений не будет и сборщик мусора удалит этот маркер. Возможно тут можно провести рефакторинг, но пока нет возможности
Все изменения я смержил в мастер. Новую версию в npm пока выкатить не могу - не приходит письмо с двухфакторкой. Надеюсь это сбой на стороне npm а не умышленная блокировка.
Для установки версии с фиксом можно использовать коммит bdce4a38eca076729c3334d1023cd684966a6c6f чтобы зафиксировать версию. Надеюсь проблему с npm получится решить
Исправлено в версии 4.0.6
@ownikss @ch3rn1k обновился до "react-native-yamap": "4.0.7"
, проблема осталась. Падает с тем же сценарием, но с другой ошибкой:
Fatal Exception: java.lang.RuntimeException: Failed to remove MapObject
стектрейс:
at com.yandex.mapkit.map.internal.MapObjectCollectionBinding.remove(MapObjectCollectionBinding.java)
at ru.vvdev.yamap.view.YamapView.removeChild(YamapView.java:539)
at ru.vvdev.yamap.YamapViewManager.removeViewAt(YamapViewManager.java:240)
at ru.vvdev.yamap.YamapViewManager.removeViewAt(YamapViewManager.java:26)
at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:460)
at com.facebook.react.uimanager.UIViewOperationQueue$ManageChildrenOperation.execute(UIViewOperationQueue.java:217)
Попробую вот это решение https://github.com/yandex/mapkit-android-demo/issues/81
До чего пока дошёл:
public void removeChild(int index)
в YamapView.java
(если закомментить начинку, то краш пропадает) if (index < childs.size()) {
ReactMapObject child = childs.remove(index);
child.getMapObject().getParent().remove(child.getMapObject());
}
кажется помогло. Собираю сборку на реальный девайс для тестинга.
Смержено в 4.0.9
@ownikss @ch3rn1k
UPD:
с сожалению падения не пропали совсем, хоть их и стало где-то 1 падение на 20 ререндеров вместо 1 падения на 2 ререндера.
Стектрейс и ошибка такие же:
Периодически падает с
Fatal Exception: java.lang.RuntimeException: Failed to remove MapObject
at com.yandex.mapkit.map.internal.MapObjectCollectionBinding.remove(MapObjectCollectionBinding.java)
at ru.vvdev.yamap.view.YamapView.removeChild(YamapView.java:554)
at ru.vvdev.yamap.YamapViewManager.removeViewAt(YamapViewManager.java:252)
at ru.vvdev.yamap.YamapViewManager.removeViewAt(YamapViewManager.java:26)
at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:460)
Периодически с
Fatal Exception: java.lang.RuntimeException: Native object's weak_ptr for N6yandex4maps6mapkit3map9MapObjectE has expired
at com.yandex.mapkit.map.internal.MapObjectBinding.getParent(MapObjectBinding.java)
at ru.vvdev.yamap.view.YamapView.removeChild(YamapView.java:554)
at ru.vvdev.yamap.YamapViewManager.removeViewAt(YamapViewManager.java:252)
at ru.vvdev.yamap.YamapViewManager.removeViewAt(YamapViewManager.java:26)
at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:460)
Судя по всему это то же самое место с removeChild
. Продолжаю пробовать копать.
Попробовал сохранять в переменные MapObject child
и parent
и проверять их на != null
и isValid,
это не помогло
Предлагаю переоткрыть issue, тк проблема осталась
Пример кода в removeChild, с которым падает
public void removeChild(int index) {
if (index < childs.size()) {
ReactMapObject child = childs.remove(index);
if (child != null) {
MapObject childMapObject = child.getMapObject();
if (childMapObject.isValid()) {
MapObjectCollection parent = childMapObject.getParent();
if (parent.isValid() && childMapObject.isValid()) {
parent.remove(childMapObject);
}
}
}
}
}
Пример кода в removeChild, с которым падает
public void removeChild(int index) { if (index < childs.size()) { ReactMapObject child = childs.remove(index); if (child != null) { MapObject childMapObject = child.getMapObject(); if (childMapObject.isValid()) { MapObjectCollection parent = childMapObject.getParent(); if (parent.isValid() && childMapObject.isValid()) { parent.remove(childMapObject); } } } } }
Могу ошибаться, но как то странно, что childs.remove(index)
присваивается в переменную, хотя это же вроде метод удаления элемента массива по индексу, хм
Пример кода в removeChild, с которым падает
public void removeChild(int index) { if (index < childs.size()) { ReactMapObject child = childs.remove(index); if (child != null) { MapObject childMapObject = child.getMapObject(); if (childMapObject.isValid()) { MapObjectCollection parent = childMapObject.getParent(); if (parent.isValid() && childMapObject.isValid()) { parent.remove(childMapObject); } } } } }
Могу ошибаться, но как то странно, что
childs.remove(index)
присваивается в переменную, хотя это же вроде метод удаления элемента массива по индексу, хм
Это нормально, в java у массивов remove
возвращает объект, который ремувнули
@ownikss @ch3rn1k
там вышла новая версия мапкита https://yandex.ru/dev/maps/mapkit/doc/dg/concepts/versions.html
в изменениях есть пункт Оптимизировано потребление памяти.
В целом, вполне вероятно, что там есть проблемы с памятью при рендере большого числа маркеров-компонентов и из-за них прилага и падает, так что мб имеет смысл попробовать обновиться.
P.S. Вчера делал ещё подход к починке removeChild
:
synchronized
, чтобы избежать возможности нескольких потоков удалять маркеры параллельноisVisible
, != null
removeChild
ещё раз, пока прошлый полностью не выполнится. Ничего не помогло
Краш в
Рендерю компоненты
Marker
, внутри которых лежат компоненты с фиксированной шириной и без указания высоты (при указании фиксированной высоты тоже падает).Маркеры рендерю по данным из редакса, которые обновляются при изменении положения карты.
Падает не всегда при 1 рендере меркеров, иногда удается 3-4 раза поменять позицию на карте до того, как упадёт
Окружение
StackTrace:
Fatal Exception: com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'point' of a view managed by: YamapMarker
... `
Caused by java.lang.RuntimeException: Native object's weak_ptr for N6yandex4maps6mapkit3map9MapObjectE has expired
... `
Видео воспроизведения
https://user-images.githubusercontent.com/15292833/168269687-bff775d2-68b9-4ab9-b6d3-65ab5bea9878.mp4