package org.osmdroid.tileprovider;
import java.util.LinkedHashMap;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.Log;
import org.osmdroid.api.IMapView;
import org.osmdroid.config.Configuration;
import org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants;
public class LRUMapTileCache extends LinkedHashMap<MapTile, Drawable> {
public interface TileRemovedListener {
void onTileRemoved(MapTile mapTile);
}
private static final long serialVersionUID = -541142277575493335L;
private int mCapacity;
private TileRemovedListener mTileRemovedListener;
public LRUMapTileCache(final int aCapacity) {
super(aCapacity + 2, 0.1f, true);
mCapacity = aCapacity;
}
public void ensureCapacity(final int aCapacity) {
if (aCapacity > mCapacity) {
Log.i(IMapView.LOGTAG, "Tile cache increased from " + mCapacity + " to " + aCapacity);
mCapacity = aCapacity;
}
}
@Override
public Drawable remove(final Object aKey) {
final Drawable drawable = super.remove(aKey);
// Only recycle if we are running on a project less than 2.3.3 Gingerbread.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
if (drawable instanceof BitmapDrawable) {
final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap != null) {
bitmap.recycle();
}
}
}
if (getTileRemovedListener() != null && aKey instanceof MapTile)
getTileRemovedListener().onTileRemoved((MapTile) aKey);
if (drawable instanceof ReusableBitmapDrawable)
BitmapPool.getInstance().returnDrawableToPool((ReusableBitmapDrawable) drawable);
return drawable;
}
@Override
public void clear() {
// remove them all individually so that they get recycled
while (!isEmpty()) {
remove(keySet().iterator().next());
}
// and then clear
super.clear();
}
@Override
protected boolean removeEldestEntry(final java.util.Map.Entry<MapTile, Drawable> aEldest) {
if (size() > mCapacity) {
final MapTile eldest = aEldest.getKey();
if (Configuration.getInstance().isDebugMode()) {
Log.d(IMapView.LOGTAG,"LRU Remove old tile: " + eldest);
}
remove(eldest);
// don't return true because we've already removed it
}
return false;
}
public TileRemovedListener getTileRemovedListener() {
return mTileRemovedListener;
}
public void setTileRemovedListener(TileRemovedListener tileRemovedListener) {
mTileRemovedListener = tileRemovedListener;
}
}