首页 > 解决方案 > 华为 MapView 碎片泄漏

问题描述

我有Bottom Navigation View4 个选项卡,其中一个包含Huawei MapView. 当我从包含 MapView 的选项卡 A 切换到选项卡 B 时,Leak Canary显示与相关的内存泄漏MapView

Fragment仅包含MapView,没有任何额外的视图

class MapFragment : BaseFragment(R.layout.fragment_map), OnMapReadyCallback  {

    private var hMap: HuaweiMap? = null

    companion object {
        private const val MAPVIEW_BUNDLE_KEY = "MapViewBundleKey"
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initHuaweiMap(savedInstanceState)
    }


    private fun initHuaweiMap(savedInstanceState: Bundle?) {
        var mapViewBundle: Bundle? = null
        if (savedInstanceState != null) {
            mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY)
        }
        map_view?.apply {
            onCreate(mapViewBundle)
            getMapAsync(this@MapFragment)
        }
    }

    override fun onMapReady(map: HuaweiMap?) {
        hMap = map
        hMap?.setMapStyle(MapStyleOptions.loadRawResourceStyle(requireContext(), R.raw.mapstyle_night_hms))
        hMap?.isMyLocationEnabled = false // Enable the my-location overlay.
        hMap?.uiSettings?.isMyLocationButtonEnabled = false // Enable the my-location icon.
        hMap?.uiSettings?.isZoomControlsEnabled = false // Disable zoom-in zoom-out buttons
    }


    override fun onStart() {
        map_view?.onStart()
        super.onStart()
    }

    override fun onStop() {
        map_view?.onStop()
        super.onStop()
    }

    override fun onDestroy() {
        map_view?.onDestroy()
        super.onDestroy()
    }

    override fun onPause() {
        map_view?.onPause()
        super.onPause()
    }

    override fun onResume() {
        map_view?.onResume()
        super.onResume()
    }

    override fun onLowMemory() {
        map_view?.onLowMemory()
        super.onLowMemory()
    }

    override fun onDestroyView() {
        hMap?.clear()
        hMap = null
        map_view?.onDestroy()
        super.onDestroyView()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        var mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY)
        if (mapViewBundle == null) {
            mapViewBundle = Bundle()
            outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle)
        }
        map_view?.onSaveInstanceState(mapViewBundle)
    }
}

我的布局文件

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".ui.tabs.profile.Mapragment">

    <com.huawei.hms.maps.MapView
        android:id="@+id/map_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:cameraZoom="14"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

我把所有与 MapView 相关的生命周期方法,但仍然导致内存泄漏

华为 MapView 内存泄漏

它说的最后一步;

MapFragment 收到 Fragment#onDestroyView() 回调(应清除对其视图的引用以防止泄漏)

我清除了参考,onDestroyView但仍然得到同样的错误。如何防止这种内存泄漏?

标签: androidhuawei-mobile-serviceshuawei-map-kit

解决方案


问题可能是地图在被破坏后仍在继续检查位置。尝试插入hMap?.setMyLocationEnabled(false) ; 进入onDestroy()以强制它在被销毁后不再跟踪位置。


推荐阅读