Android 片段内存泄漏中的MapView
我已经像这样在片段中添加了贴图Android 片段内存泄漏中的MapView,android,google-maps,android-fragments,memory-leaks,Android,Google Maps,Android Fragments,Memory Leaks,我已经像这样在片段中添加了贴图 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_l
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();
}
}
我从这篇文章中得到了这个想法
它正在工作,但我遇到的问题是内存泄漏。我制作了第二个片段(用addToBackStack(null)
替换(替换而不是添加)它),只需查看和带有manager.popbackimmediate()
的按钮,我正在用Canary Leak(没有捕获任何内容)和Android Profiler测试它。每次我转到那个片段并返回地图片段时,内存都会增加大约10MB
为了进行测试,我删除了MapView
,当返回时,交换片段的内存没有增加,所以我可以说问题出在MapView上
我还尝试将mapView.onDestroy()
放在onDestroyView()
(这里也添加了mapView=null
)中,正如有人在那篇文章的评论中所说的那样,这样做有一定的帮助,并且在交换时内存没有被填满(仍然是,但每次交换时都没有1-5MB那么糟糕)。但问题是,当我交换了20多次碎片后,应用程序崩溃了,我出现了错误
java.lang.NullPointerException:尝试在以下位置获取空数组的长度:
DirectByteBuffer.put(DirectByteBuffer.java:385)
所以我去搜索是什么导致了这一点,我找到了关于这一点的两个帖子(将只发布一个)
我在那里尝试了这个解决方案,但没有成功(我仍然得到这个错误)。但正如我看到的,有些人仍在经历这种情况。我也读了其他帖子,但没有找到任何关于我的案例。现在来回答我的问题
交换片段的最佳方法是附加和分离片段
public void replaceFragment(Fragment fragment)
{
fm = FragmentManager;
ft = fm.BeginTransaction();
if (fragment == MapsFragment)
{
if (MapsFragment == null)
{
MapsFragment = new PoSLocationMapView(this);
ft.Add(Resource.Id.frame_container, MapsFragment, "MapsFragment");
}
else
{
ft.Detach(FragmentManager.FindFragmentByTag("ListFragment"));
ft.Attach(MapsFragment);
}
}
else if (fragment == ListFragment)
{
if (ListFragment == null)
{
ListFragment = new ServicePointDHLList(this);
ft.Add(Resource.Id.frame_container, ListFragment, "ListFragment");
}
else
{
ft.Detach(FragmentManager.FindFragmentByTag("MapsFragment"));
ft.Attach(ListFragment);
}
}
ft.SetTransition(FragmentTransit.FragmentOpen);
ft.Commit();
}
private void setCurrentTabFragment(int tabPosition)
{
switch (tabPosition)
{
case 0:
replaceFragment(MapsFragment);
break;
case 1:
replaceFragment(ListFragment);
break;
}
}
这就是我最近在Xamarin android上的做法
这段代码在一个活动中,我需要两个选项卡,所以我使用setCurrentTabFragment()在这两个选项卡之间进行交换
您可以轻松地将其转换为Java Android
以及内存泄漏问题
使用onLowMemory()中的java系统垃圾收集器,也可以使用片段的onDestroy()中的GoogleMapsObject.Clear()清除googlemaps对象,但请确保在不再需要映射的地方调用此Clear()方法,以便使用它清除由于所有标记而创建的位图缓存
祝你好运 好吧,我知道问题出在哪里了(我想是的),因为我再也看不到地图上的漏洞了 我将此添加到onDestroyView的片段中
@Override
public void onDestroyView() {
googleMap.clear()
mMapView?.onDestroy()
mMapView = null
super.onDestroyView()
}
我在一篇博文中读到,googleMap.clear()和MapView onDestroy()应该在onDestroyView()中,而不是在onDestroy()方法中,因为没有调用该回调函数。这消除了错误,但替换片段时仍然存在内存问题。一旦我在那里添加了mMapView=null,我可以告诉你哪里没有任何泄漏(我会更好地调试它,如果我发现任何新的,我会在这里发布) 谢谢你的意见。如果有任何查询,将尝试类似此还原的操作。如果在
onDestroy()
中有类似的代码,请将其移动到onDestroyView()
。现在,当交换两个地图片段时,内存使用率在一瞬间下降了50%,然后又回到了片段交换之前的值,所以我假设它已经解决了。