片段内存泄漏中的MapView

MeP*_*ePo 2 android google-maps memory-leaks android-fragments

我已经像这样添加了Map to Fragment

public class SomeFragment extends Fragment {

MapView mapView;
GoogleMap map;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.some_layout, container, false);

    // Gets the MapView from the XML layout and creates it
    mapView = (MapView) v.findViewById(R.id.mapview);
    mapView.onCreate(savedInstanceState);

    // Gets to GoogleMap from the MapView and does initialization stuff
    map = mapView.getMap();
    map.getUiSettings().setMyLocationButtonEnabled(false);
    map.setMyLocationEnabled(true);

    // Needs to call MapsInitializer before doing any CameraUpdateFactory calls
    try {
        MapsInitializer.initialize(this.getActivity());
    } catch (GooglePlayServicesNotAvailableException e) {
        e.printStackTrace();
    }

    // Updates the location and zoom of the MapView
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
    map.animateCamera(cameraUpdate);

    return v;
}

@Override
public void onResume() {
    mapView.onResume();
    super.onResume();
}

@Override
public void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mapView.onLowMemory();
}

}
Run Code Online (Sandbox Code Playgroud)

我从这篇文章中得到了这个想法

/sf/answers/1832220141/

它正在工作,但我遇到的问题是内存泄漏.我已经制作了第二个Fragment(替换(替换不添加)addToBackStack(null))只有视图和一个按钮,manager.popBackStackImmediate()我正在测试它与Canary Leak(没有捕获任何东西)和Android Profiler.每次我去那个片段并返回地图片段内存上升大约10MB.

为了测试我移除了MapView并且交换片段在返回时没有增加内存,所以我可以说问题在于MapView.

我也试图把mapView.onDestroy()onDestroyView()(也加入mapView = null这里)有人在该职位,是做了一些帮助和交换时,内存没有得到填补的评论说,(它仍然是,但它不是那么糟糕1 - 5 MB,每次我做交换).但问题是当我交换碎片20次以上应用程序崩溃并且我收到错误

java.lang.NullPointerException:尝试在java.nio.DirectByteBuffer.put获取null数组的长度(DirectByteBuffer.java:385)

所以我去搜索造成这种情况的原因,我发现了几个关于此的帖子(只会发布一个)

为什么google map v2突然崩溃了java.lang.NullPointerException:尝试获取null数组的长度?

我尝试了那里的解决方案,它没有工作(我仍然得到这个错误).但正如我所看到的,有些人仍在经历这一点.我也读过其他帖子,但没有找到我的案例.所以现在我的问题.

  1. 我在这里失踪了什么?我应该如何在没有"膨胀"(保持对MapView的引用)内存的情况下交换片段.

  2. 我可以在Activity中创建MapView并在此片段中引用它(这样它不会每次都重新创建),因为我的应用程序中的所有内容都围绕着它

  3. 将地图放在一个活动中,将其余的片段放在其他活动中(所有片段都以某种方式与地图进行通信,这就是我为此开始这样做的原因)

  4. 也许我做错了,可能有更好的方法吗?(不确定)

MeP*_*ePo 7

好吧,我想出了问题是什么(我想我做了)因为我不再看到地图上的泄漏了.

我将其添加到片段onDestroyView中

@Override
public void onDestroyView() {
    googleMap.clear()
    mMapView?.onDestroy()
    mMapView = null
    super.onDestroyView()
}
Run Code Online (Sandbox Code Playgroud)

我在其中一篇文章中读到googleMap.clear()和MapView onDestroy()应该在onDestroyView()而不是在onDestroy()方法中.摆脱了错误,但替换片段的内存问题仍然存在.一旦我添加mMapView = null从我可以告诉哪里没有任何泄漏(我仍然会更好地调试这个,如果我发现任何新的,我会在这里发布).

  • 在`onDestroy()`中有类似的代码,将它移动到`onDestroyView()`.现在,当交换两个映射片段时,内存使用会在一瞬间下降大约50%,然后返回到与片段交换之前相似的值,因此我认为它已经解决了. (2认同)