I'm using MapView
v2 in my application (not MapFragment
) and it's causing a memory leak. The leak occurs when I pass the Activity context to the MapView constructor. If I pass the Application Context to the MapView constructor the memory leak goes away, however the MapView starts performing badly when I scroll the ScrollView it's in.
Here's a snapshot of where the leak is happening:
The relevant code in MapView
is:
public class MapView extends android.widget.FrameLayout {
private final com.google.android.gms.maps.MapView.b gD;
static class b extends com.google.android.gms.dynamic.a<com.google.android.gms.maps.MapView.a> {
private final android.content.Context mContext;
// Here's the Context MapView is leaking
}
static class a implements com.google.android.gms.dynamic.LifecycleDelegate {
// More stuff in here
}
}
I've been messing with MapView
for a few weeks now trying to get it to behave correctly in a ScrollView
, to no avail. I'm about to give up on it.
Also, the snapshot()
method that was recently added isn't an option because I have already tried it, and it doesn't give a reliable snapshot of the map. I have an open question on this here, and another related open question here and here, all of which have not been answered.
Possibily related to danielgomezrico's answer, there is a confirmed bug related to my location layer in MapView
that leaks memory.
The workaround is to make sure you disable my location using GoogleMap.setMyLocationEnabled(false)
before the map is destroyed. Also make sure to call other map view's lifecycle methods as well.
private MapView mMapView;
private GoogleMap mMap;
...
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
@Override
public void onDestroy() {
super.onDestroy();
if (mMap != null) {
mMap.setMyLocationEnabled(false);
}
mMapView.onDestroy();
}
I've been messing with MapView for a few weeks now trying to get it to behave correctly in a ScrollView, to no avail. I'm about to give up on it.
Honestly, that's for the best. MapView is likely never going to play nice inside of a ScrollView. There are a host of bugs that crop up when this combination is used; vertical lag, the MapView rendering over the ActionBar, vertical scrolling simply not working, etc. Removing the ScrollView is not only preferred but most likely required.
That said, if you absolutely must do this, because of client constraints for example, you have two options.
You can use Snapshot
& the SnapshotReady
callback; when the callback is fired, replace the MapView with an ImageView of the snapshot. You lose interactivity but you also lose the problems you're experiencing. (You're claiming this doesn't work or draws an incomplete bitmap, though I haven't run into that issue. I'm not sure how you're implementing it.)
Write a custom class extending the MapView, override onTouchEvent and for whatever motion events you need to fix (probably ACTION_DOWN
and ACTION_UP
), manually control whether or not the parent (the ScrollView) can intercept the action. Use something like this.getParent().requestDisallowInterceptTouchEvent(true|false)
depending on your case. Check the Android docs for more info on that method.
I hope that helps!
In project that I was working we had similar issue. We were using mapView inside viewholder. Solution was to call onPause and then onDestroy on mapview. After that memory leaks were not observed.
Are you using it inside a fragment? Maybe related to this bug https://code.google.com/p/android/issues/detail?id=185902