SIGABRT (Pure virtual function called) on maplibre android v11.5.0 (latest version)
Describe the bug An exception in native code happens that crash the app.
To Reproduce Sorry, I am not sure how to reproduce this. It happens after 10-15 seconds while using the map. Sometimes it happens after a click or a zoom change.
Expected behavior No crash should happen.
Platform information (please complete the following information): Android 15 (not relevant, happens on a variety of versions)
I've attached a stack trace. Let me know if you need anything else. log_maplibre.txt
I've tracked down the bug to the following function in my code. The crash always happen when calling copyLayer.setProperties(textSize1)
private void addHighlightedLayer(@NonNull List<Layer> lstLayers,
@NonNull List<Feature> lstFeatures,
int nRepeatCount,
int nLineWidth,
@Nullable Float nOpacity,
@Nullable Float nMinZoom,
@Nullable Float nMaxZoom) {
Style style = getStyle();
if (style == null) {
throw new IllegalStateException("Style not loaded yet");
}
int nCount = lstLayers.size();
for (String sIdLayer : lstHighlightedLayerIds) {
style.removeLayer(sIdLayer);
}
for (String sIdSource : lstHighlightedSourceIds) {
style.removeSource(sIdSource);
}
lstHighlightedLayerIds.clear();
lstHighlightedSourceIds.clear();
for (int i = 0; i < nCount; i++) {
Layer layer = lstLayers.get(i);
Feature feature = lstFeatures.get(i);
FeatureCollection featureCollection = FeatureCollection.fromFeature(feature);
String sSourceId = Utils.getRandomAlphabeticString(16);
style.addSource(new GeoJsonSource(sSourceId, featureCollection));
lstHighlightedSourceIds.add(sSourceId);
if (layer instanceof SymbolLayer) {
SymbolLayer symbolLayer = (SymbolLayer) layer;
String sLayerId = Utils.getRandomAlphabeticString(16);
lstHighlightedLayerIds.add(sLayerId);
SymbolLayer copyLayer = new SymbolLayer(sLayerId, sSourceId);
Expression filter = symbolLayer.getFilter();
if (filter != null) {
copyLayer.setFilter(filter);
}
PropertyValue<Float> textSize = symbolLayer.getTextSize();
float nFinalOpacity = nOpacity == null ? 1f : nOpacity;
PropertyValue<Float> opacity = PropertyFactory.iconOpacity(nFinalOpacity);
copyLayer.setProperties(symbolLayer.getTextFont(),
symbolLayer.getTextField(),
symbolLayer.getTextAllowOverlap(),
symbolLayer.getVisibility(),
symbolLayer.getTextColor(),
symbolLayer.getTextHaloWidth(),
symbolLayer.getTextHaloColor(),
opacity);
float nFinalMinZoom = nMinZoom == null ? symbolLayer.getMinZoom() : nMinZoom;
float nFinalMaxZoom = nMaxZoom == null ? symbolLayer.getMaxZoom() : nMaxZoom;
copyLayer.setMinZoom(nFinalMinZoom);
copyLayer.setMaxZoom(nFinalMaxZoom);
selectedLayerAnimator = new ValueAnimator();
selectedLayerAnimator.setObjectValues(textSize.value, textSize.value + 50);
selectedLayerAnimator.setDuration(2000);
// Impar para volver a origen
selectedLayerAnimator.setRepeatCount(nRepeatCount);
selectedLayerAnimator.setRepeatMode(ValueAnimator.REVERSE);
selectedLayerAnimator.addUpdateListener(animator -> {
try {
PropertyValue<Float> textSize1 = PropertyFactory.textSize((float) animator.getAnimatedValue());
copyLayer.setProperties(textSize1);
} catch (Exception ex) {
ex.printStackTrace();
}
});
selectedLayerAnimator.start();
style.addLayerAbove(copyLayer, symbolLayer.getId());
} else if (layer instanceof LineLayer) {
LineLayer lineLayer = (LineLayer) layer;
String sLayerId = Utils.getRandomAlphabeticString(16);
lstHighlightedLayerIds.add(sLayerId);
LineLayer copyLayer = new LineLayer(sLayerId, sSourceId);
Expression filter = lineLayer.getFilter();
if (filter != null) {
copyLayer.setFilter(filter);
}
PropertyValue<Float> lineWidth = lineLayer.getLineWidth();
float nFinalOpacity = nOpacity == null ? 1f : nOpacity;
PropertyValue<Float> opacity = PropertyFactory.lineOpacity(nFinalOpacity);
lineWidth = new PropertyValue<>(lineWidth.name, lineWidth.value);
copyLayer.setProperties(lineWidth,
lineLayer.getVisibility(),
lineLayer.getLineColor(),
lineLayer.getLineWidth(),
opacity);
float nFinalMinZoom = nMinZoom == null ? lineLayer.getMinZoom() : nMinZoom;
float nFinalMaxZoom = nMaxZoom == null ? lineLayer.getMaxZoom() : nMaxZoom;
copyLayer.setMinZoom(nFinalMinZoom);
copyLayer.setMaxZoom(nFinalMaxZoom);
selectedLayerAnimator = new ValueAnimator();
selectedLayerAnimator.setObjectValues(lineWidth.value, lineWidth.value + nLineWidth);
selectedLayerAnimator.setDuration(2000);
// Impar para volver a origen
selectedLayerAnimator.setRepeatCount(nRepeatCount);
selectedLayerAnimator.setRepeatMode(ValueAnimator.REVERSE);
selectedLayerAnimator.addUpdateListener(animator -> {
try {
PropertyValue<Float> textSize1 = PropertyFactory.lineWidth((float) animator.getAnimatedValue());
copyLayer.setProperties(textSize1);
} catch (Exception ex) {
ex.printStackTrace();
}
});
selectedLayerAnimator.start();
style.addLayerAbove(copyLayer, lineLayer.getId());
}
}
}
I use a ValueAnimator to grow/shrink a selected feature. I only cancel() the ValueAnimator when another feature is selected. My guess is that at some point the layer is invalid and the memory gets corrupted.
Is there any other (built-in or not) way I could achieve this effect?
We're getting crashes on v11.5.1 that might be related to this error tombstone_00.txt tombstone_01.txt