You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中Mapbox内存泄漏问题及内存释放方法咨询

Jetpack Compose中Mapbox内存释放方案

在Compose里使用Mapbox出现内存持续攀升,核心原因是MapView的资源没有随Compose视图销毁而正确释放,按以下步骤处理即可解决:

1. 绑定MapView与Compose视图生命周期

AndroidView提供了update和onRelease回调,用来同步MapView的生命周期方法:

  • 视图可见时调用mapView.onStart()、mapView.onResume()
  • 视图不可见时调用mapView.onStop()、mapView.onPause()
  • 视图销毁时调用mapView.onDestroy(),同时手动清理所有自定义资源

2. 销毁前主动清理自定义资源

释放MapView前,必须移除所有添加的图层、数据源、ViewAnnotation,避免引用残留:

  • 移除自定义的GeoJsonSource和LineLayer
  • 清空ViewAnnotationManager中的所有注解视图
  • 避免全局持有MapView引用,改用Compose的remember在局部作用域存储

3. 修改后的完整代码示例

// 用remember在Compose局部作用域存储MapView,避免全局引用和重复创建
val mapView = remember {
    MapView(LocalContext.current).apply {
        scalebar.enabled = false
        compass.enabled = false
        gestures.scrollEnabled = false
        gestures.pitchEnabled = false
    }
}

AndroidView(
    modifier = Modifier
        .height(240.dp)
        .clip(RoundedCornerShape(topStart = 10.dp, topEnd = 10.dp)),
    factory = { mapView },
    update = { view ->
        // 视图可见时启动MapView生命周期
        view.onStart()
        view.onResume()
        
        view.getMapboxMap().loadStyleUri("mapbox://styles/.../....") { sty ->
            trip.listOfLatLon.let { points ->
                val polygon = Polygon.fromLngLats(listOf(points))
                val cameraPosition = view.getMapboxMap().cameraForGeometry(
                    polygon,
                    padding = EdgeInsets(220.0, 320.0, 220.0, 320.0)
                )

                val viewAnnotationManager = view.viewAnnotationManager
                // 先清空旧注解,避免重复积累
                viewAnnotationManager.clearAllViewAnnotations()
                
                viewAnnotationManager.addViewAnnotation(
                    R.layout.camera_report_annotation,
                    viewAnnotationOptions {
                        geometry(points[0])
                        allowOverlap(false)
                        anchor(ViewAnnotationAnchor.BOTTOM)
                        visible(true)
                    }
                )
                viewAnnotationManager.addViewAnnotation(
                    R.layout.police_report_annotation,
                    viewAnnotationOptions {
                        geometry(points[trip.listOfLatLon.size - 1])
                        allowOverlap(false)
                        anchor(ViewAnnotationAnchor.CENTER)
                        visible(true)
                    }
                )
                view.getMapboxMap().setCamera(cameraPosition)
            }
            
            // 先移除旧的数据源和图层,避免重复添加导致内存泄漏
            sty.getSource("line")?.let { sty.removeSource(it) }
            sty.getLayer("linelayer")?.let { sty.removeLayer(it) }
            
            val data = geoJsonSource("line") {
                featureCollection(FeatureCollection.fromFeature(feature))
            }
            sty.addSource(data)
            sty.addLayer(lineLayer("linelayer", "line") {
                lineCap(LineCap.ROUND)
                lineJoin(LineJoin.ROUND)
                lineWidth(4.0)
                lineColor("#495CE8")
            })
        }
    },
    onRelease = { view ->
        // 视图销毁时彻底释放资源
        val mapboxMap = view.getMapboxMap()
        val style = mapboxMap.getStyle()
        
        // 移除自定义图层和数据源
        style?.let {
            it.getLayer("linelayer")?.let { layer -> it.removeLayer(layer) }
            it.getSource("line")?.let { source -> it.removeSource(source) }
        }
        
        // 清空所有ViewAnnotation
        view.viewAnnotationManager.clearAllViewAnnotations()
        
        // 调用MapView生命周期销毁方法
        view.onPause()
        view.onStop()
        view.onDestroy()
    }
)

关键注意事项

  • 不要用全局变量持有MapView,remember能确保Compose重组时不会重复创建实例,且作用域可控
  • 每次update时先清理旧资源,避免重复添加导致内存堆积
  • onRelease中必须调用mapView.onDestroy(),这是释放MapView核心内存的关键步骤

内容的提问来源于stack exchange,提问作者Kawan Osman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:45:38