Fix UI memory leak on rotate / Merge with master special tests will be needed of this branch
Conflicts: OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java
This commit is contained in:
parent
5e2b0b013d
commit
6d9567fd98
5 changed files with 80 additions and 24 deletions
|
@ -3,6 +3,7 @@ package net.osmand.plus;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
@ -67,22 +68,28 @@ public class OsmandSettings {
|
|||
}
|
||||
|
||||
private abstract class PreferenceWithListener<T> implements OsmandPreference<T> {
|
||||
private List<StateChangedListener<T>> l = null;
|
||||
private List<WeakReference<StateChangedListener<T>>> l = null;
|
||||
|
||||
@Override
|
||||
public void addListener(StateChangedListener<T> listener) {
|
||||
if(l == null) {
|
||||
l = new LinkedList<StateChangedListener<T>>();
|
||||
l = new LinkedList<WeakReference<StateChangedListener<T>>>();
|
||||
}
|
||||
if(!l.contains(listener)) {
|
||||
l.add(listener);
|
||||
if(!l.contains(new WeakReference<StateChangedListener<T>>(listener))) {
|
||||
l.add(new WeakReference<StateChangedListener<T>>(listener));
|
||||
}
|
||||
}
|
||||
|
||||
public void fireEvent(T value){
|
||||
if (l != null) {
|
||||
for (StateChangedListener<T> t : l) {
|
||||
t.stateChanged(value);
|
||||
Iterator<WeakReference<StateChangedListener<T>>> it = l.iterator();
|
||||
while(it.hasNext()) {
|
||||
StateChangedListener<T> t = it.next().get();
|
||||
if(t == null) {
|
||||
it.remove();
|
||||
} else {
|
||||
t.stateChanged(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +97,13 @@ public class OsmandSettings {
|
|||
@Override
|
||||
public void removeListener(StateChangedListener<T> listener) {
|
||||
if(l != null) {
|
||||
l.remove(listener);
|
||||
Iterator<WeakReference<StateChangedListener<T>>> it = l.iterator();
|
||||
while(it.hasNext()) {
|
||||
StateChangedListener<T> t = it.next().get();
|
||||
if(t == listener) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,9 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
if(!mapView.isLayerVisible(distanceCalculatorLayer)) {
|
||||
activity.getMapView().addLayer(distanceCalculatorLayer, 4.5f);
|
||||
}
|
||||
registerWidget(activity);
|
||||
if(distanceControl == null) {
|
||||
registerWidget(activity);
|
||||
}
|
||||
} else {
|
||||
MapInfoLayer mapInfoLayer = activity.getMapLayers().getMapInfoLayer();
|
||||
if(distanceCalculatorLayer != null) {
|
||||
|
|
|
@ -90,6 +90,10 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
|
|||
|
||||
@Override
|
||||
public void registerLayers(MapActivity activity) {
|
||||
registerWidget(activity);
|
||||
}
|
||||
|
||||
private void registerWidget(MapActivity activity) {
|
||||
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
|
||||
monitoringControl = createMonitoringControl(activity);
|
||||
|
||||
|
@ -100,8 +104,17 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
|
|||
|
||||
@Override
|
||||
public void updateLayers(OsmandMapTileView mapView, MapActivity activity) {
|
||||
if(monitoringControl == null) {
|
||||
registerLayers(activity);
|
||||
if (isActive()) {
|
||||
if (monitoringControl == null) {
|
||||
registerWidget(activity);
|
||||
}
|
||||
} else {
|
||||
if (monitoringControl != null) {
|
||||
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
|
||||
layer.removeSideWidget(monitoringControl);
|
||||
layer.recreateControls();
|
||||
monitoringControl = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
|
|||
import net.osmand.plus.osmo.OsMoService.SessionInfo;
|
||||
import net.osmand.plus.views.MapInfoLayer;
|
||||
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
|
@ -169,21 +170,49 @@ public class OsMoPlugin extends OsmandPlugin implements OsMoReactor {
|
|||
super.registerMapContextMenuActions(mapActivity, latitude, longitude, adapter, selectedObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayers(OsmandMapTileView mapView, MapActivity activity) {
|
||||
if(isActive()) {
|
||||
if(olayer == null) {
|
||||
registerLayers(activity);
|
||||
}
|
||||
if(osmoControl == null) {
|
||||
registerSideWidget(activity);
|
||||
}
|
||||
} else {
|
||||
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
|
||||
if (layer != null && osmoControl != null) {
|
||||
layer.removeSideWidget(osmoControl);
|
||||
osmoControl = null;
|
||||
layer.recreateControls();
|
||||
}
|
||||
if(olayer != null) {
|
||||
activity.getMapView().removeLayer(olayer);
|
||||
olayer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerLayers(MapActivity activity) {
|
||||
super.registerLayers(activity);
|
||||
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
|
||||
osmoControl = createOsMoControl(activity);
|
||||
layer.registerSideWidget(osmoControl,
|
||||
R.drawable.ic_osmo_dark, R.string.osmo_control, "osmo_control", false, 18);
|
||||
layer.recreateControls();
|
||||
|
||||
registerSideWidget(activity);
|
||||
if(olayer != null) {
|
||||
activity.getMapView().removeLayer(olayer);
|
||||
}
|
||||
olayer = new OsMoPositionLayer(activity, this);
|
||||
activity.getMapView().addLayer(olayer, 5.5f);
|
||||
}
|
||||
|
||||
private void registerSideWidget(MapActivity activity) {
|
||||
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
|
||||
if (layer != null) {
|
||||
osmoControl = createOsMoControl(activity);
|
||||
layer.registerSideWidget(osmoControl, R.drawable.ic_osmo_dark, R.string.osmo_control, "osmo_control",
|
||||
false, 18);
|
||||
layer.recreateControls();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapActivityPause(MapActivity activity) {
|
||||
|
|
|
@ -731,24 +731,23 @@ public class MapRenderRepositories {
|
|||
Bitmap reuse = prevBmp;
|
||||
this.prevBmp = this.bmp;
|
||||
this.prevBmpLocation = this.bmpLocation;
|
||||
if (reuse != null && reuse.getWidth() == currentRenderingContext.width && reuse.getHeight() == currentRenderingContext.height) {
|
||||
// necessary for transparent, otherwise 2 times smaller
|
||||
Config cfg = transparent ? Config.ARGB_8888 : Config.RGB_565;
|
||||
if (reuse != null && reuse.getWidth() == currentRenderingContext.width && reuse.getHeight() == currentRenderingContext.height &&
|
||||
cfg == reuse.getConfig()) {
|
||||
bmp = reuse;
|
||||
bmp.eraseColor(currentRenderingContext.defaultColor);
|
||||
} else {
|
||||
if(reuse != null){
|
||||
log.warn(String.format("Create new image ? %d != %d (w) %d != %d (h) ", currentRenderingContext.width, reuse.getWidth(), currentRenderingContext.height, reuse.getHeight()));
|
||||
}
|
||||
if(transparent) {
|
||||
// necessary
|
||||
bmp = Bitmap.createBitmap(currentRenderingContext.width, currentRenderingContext.height, Config.ARGB_8888);
|
||||
} else {
|
||||
// better picture ?
|
||||
bmp = Bitmap.createBitmap(currentRenderingContext.width, currentRenderingContext.height, Config.ARGB_8888);
|
||||
bmp = Bitmap.createBitmap(currentRenderingContext.width, currentRenderingContext.height, cfg);
|
||||
if(reuse != null) {
|
||||
reuse.recycle();
|
||||
}
|
||||
}
|
||||
this.bmp = bmp;
|
||||
this.bmpLocation = tileRect;
|
||||
|
||||
if(nativeLib != null) {
|
||||
renderer.generateNewBitmapNative(currentRenderingContext, nativeLib, cNativeObjects, bmp, renderingReq, notifyList);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue