Android开发中如何释放Google Map占用内存?LeakCanary检测到泄漏
在Android Fragment中使用Google Map的内存泄漏修复方案
在Fragment中集成Google Map后,LeakCanary持续提示内存未释放,可通过以下步骤彻底修复:
你当前的实现代码
private var map: GoogleMap? = null private var mapFragment: SupportMapFragment? = null override fun onMapReady(googleMap: GoogleMap) { map = googlemap } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) mapFragment = childFragmentManager.findFragmentById(R.id.mapView) as SupportMapFragment mapFragment?.getMapAsync(this) } override fun onDestroyView() { super.onDestroyView() map?.clear() mapFragment?.onDestroy() }
核心修复步骤
- 切断GoogleMap强引用:调用
map?.clear()清理地图内容后,必须将map置为null,彻底解除Fragment对地图实例的持有 - 正确移除MapFragment:不要直接调用
mapFragment?.onDestroy(),而是通过childFragmentManager主动移除该Fragment,确保FragmentManager不再保留它的引用 - 清理自定义监听:如果给GoogleMap设置过
OnMarkerClickListener、OnCameraChangeListener等自定义监听,需在销毁前手动置空解除绑定
修正后的完整代码
private var map: GoogleMap? = null private var mapFragment: SupportMapFragment? = null override fun onMapReady(googleMap: GoogleMap) { map = googleMap // 示例:如果有自定义监听,需在后续销毁时移除 // map?.setOnMarkerClickListener(this) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) mapFragment = childFragmentManager.findFragmentById(R.id.mapView) as SupportMapFragment mapFragment?.getMapAsync(this) } override fun onDestroyView() { super.onDestroyView() // 移除所有自定义监听 // map?.setOnMarkerClickListener(null) // 清理地图并切断引用 map?.clear() map = null // 从FragmentManager中移除MapFragment mapFragment?.let { fragment -> childFragmentManager.beginTransaction().remove(fragment).commitNowAllowingStateLoss() } mapFragment = null }
补充说明
- 使用
commitNowAllowingStateLoss()而非commit(),确保Fragment立即被移除,避免状态保存阶段的潜在引用残留 - 如果布局中使用的是
MapView而非SupportMapFragment,还需在onDestroy中调用mapView.onDestroy()并将mapView置为null
内容的提问来源于stack exchange,提问作者hanjiman
相关产品推荐
相关产品推荐

