osmdroid API解读(四)
来源:互联网 发布:淘宝买家秀大尺度下载 编辑:程序博客网 时间:2024/06/05 20:50
osmdroid API解读(四)
osmdroid-android模块 org.osmdroid.tileprovider包(一)
1.MapTile
地图瓦片使用观察者模式分割,瓦片由tile provider下发。本类必须保持不变,因为其备用于缓存hash map的key
public class MapTile { public static final int MAPTILE_SUCCESS_ID = 0; public static final int MAPTILE_FAIL_ID = MAPTILE_SUCCESS_ID + 1; private final int x;//瓦片的坐标位置x private final int y;//瓦片的坐标位置y private final int zoomLevel;//该瓦片缩放等级 private Date expires;//瓦片到期时间 public MapTile(final int zoomLevel, final int tileX, final int tileY) { this.zoomLevel = zoomLevel; this.x = tileX; this.y = tileY; } public Date getExpires() { return expires; } public void setExpires(Date expires) { this.expires = expires; } public int getZoomLevel() { return zoomLevel; } public int getX() { return x; } public int getY() { return y; } @Override public String toString() { return "/" + zoomLevel + "/" + x + "/" + y; } @Override public boolean equals(final Object obj) { if (obj == null) return false; if (obj == this) return true; if (!(obj instanceof MapTile)) return false; final MapTile rhs = (MapTile) obj; return zoomLevel == rhs.zoomLevel && x == rhs.x && y == rhs.y; } @Override public int hashCode() { int code = 17; code *= 37 + zoomLevel; code *= 37 + x; code *= 37 + y; return code; }}
1.1 LRUMapTileCache
瓦片集合缓存,继承自LinkedHashMap,以MapTile(用于定位图片位置)为key,Drawable为value。用于管理一系列的瓦片。
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; }}
1.2 MapTileCache
持有瓦片集合LRUMapTileCache,并有相应的瓦片操作方法
public class MapTileCache { protected final Object mCachedTilesLockObject = new Object(); protected LRUMapTileCache mCachedTiles;//持有的瓦片集合 public MapTileCache() { this(Configuration.getInstance().getCacheMapTileCount()); } //最大缓存尺寸 public MapTileCache(final int aMaximumCacheSize) { this.mCachedTiles = new LRUMapTileCache(aMaximumCacheSize); } public void ensureCapacity(final int aCapacity) { synchronized (mCachedTilesLockObject) { mCachedTiles.ensureCapacity(aCapacity); } } public Drawable getMapTile(final MapTile aTile) { synchronized (mCachedTilesLockObject) { return this.mCachedTiles.get(aTile); } } public void putTile(final MapTile aTile, final Drawable aDrawable) { if (aDrawable != null) { synchronized (mCachedTilesLockObject) { this.mCachedTiles.put(aTile, aDrawable); } } } public boolean containsTile(final MapTile aTile) { synchronized (mCachedTilesLockObject) { return this.mCachedTiles.containsKey(aTile); } } public void clear() { synchronized (mCachedTilesLockObject) { this.mCachedTiles.clear(); } }}
2.ExpirableBitmapDrawable
可过期图片,提供了不同的时间状态(更新状态 过期 缩放 没有发现 等状态)。
public class ExpirableBitmapDrawable extends BitmapDrawable { //状态 public static final int UP_TO_DATE = -1; public static final int EXPIRED = -2; public static final int SCALED = -3; public static final int NOT_FOUND = -4; private static final int defaultStatus = UP_TO_DATE; private static final int[] settableStatuses = new int[] {EXPIRED, SCALED, NOT_FOUND}; private int[] mState; public ExpirableBitmapDrawable(final Bitmap pBitmap) { super(pBitmap); mState = new int[0]; } @Override public int[] getState() { return mState; } @Override public boolean isStateful() { return mState.length > 0; } @Override public boolean setState(final int[] pStateSet) { mState = pStateSet; return true; } @Deprecated public static boolean isDrawableExpired(final Drawable pTile) { return getState(pTile) == EXPIRED; } public static int getState(final Drawable pTile) { for(final int statusItem : pTile.getState()) { for (final int statusReference : settableStatuses) { if (statusItem == statusReference) { return statusItem; } } } return defaultStatus; } /** * @deprecated use {@link #setState(Drawable, int)} instead */ @Deprecated public static void setDrawableExpired(final Drawable pTile) { setState(pTile, EXPIRED); } public static void setState(final Drawable pTile, final int status) { pTile.setState(new int[]{status}); }}
2.1 ReusableBitmapDrawable
继承自ExpirableBitmapDrawable,保持对图片使用引用跟踪。具体看内部方法。
public class ReusableBitmapDrawable extends ExpirableBitmapDrawable { private boolean mBitmapRecycled = false; private int mUsageRefCount = 0; public ReusableBitmapDrawable(Bitmap pBitmap) { super(pBitmap); } //开始使用图片 public void beginUsingDrawable() { synchronized (this) { mUsageRefCount++; } } //结束使用图片 public void finishUsingDrawable() { synchronized (this) { mUsageRefCount--; if (mUsageRefCount < 0) throw new IllegalStateException("Unbalanced endUsingDrawable() called."); } } //回收 public Bitmap tryRecycle() { synchronized (this) { if (mUsageRefCount == 0) { mBitmapRecycled = true; return getBitmap(); } } return null; } //检测是否有效 public boolean isBitmapValid() { synchronized (this) { return !mBitmapRecycled; } }}
2.2 BitmapPool
持有并管理所有的瓦片图片。
public class BitmapPool { final LinkedList<Bitmap> mPool = new LinkedList<Bitmap>(); private static BitmapPool sInstance; public static BitmapPool getInstance() { if (sInstance == null) sInstance = new BitmapPool(); return sInstance; } public void returnDrawableToPool(ReusableBitmapDrawable drawable) { Bitmap b = drawable.tryRecycle(); if (b != null && b.isMutable()) synchronized (mPool) { mPool.addLast(b); } } public void applyReusableOptions(final BitmapFactory.Options aBitmapOptions) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { aBitmapOptions.inBitmap = obtainBitmapFromPool(); aBitmapOptions.inSampleSize = 1; aBitmapOptions.inMutable = true; } } public Bitmap obtainBitmapFromPool() { synchronized (mPool) { if (mPool.isEmpty()) { return null; } else { final Bitmap bitmap = mPool.removeFirst(); if (bitmap.isRecycled()) { return obtainBitmapFromPool(); // recurse } else { return bitmap; } } } } public Bitmap obtainSizedBitmapFromPool(final int aWidth, final int aHeight) { synchronized (mPool) { if (mPool.isEmpty()) { return null; } else { for (final Bitmap bitmap : mPool) { if (bitmap.isRecycled()) { mPool.remove(bitmap); return obtainSizedBitmapFromPool(aWidth, aHeight); // recurse to prevent ConcurrentModificationException } else if (bitmap.getWidth() == aWidth && bitmap.getHeight() == aHeight) { mPool.remove(bitmap); return bitmap; } } } } return null; } public void clearBitmapPool() { synchronized (sInstance.mPool) { while (!sInstance.mPool.isEmpty()) { Bitmap bitmap = sInstance.mPool.remove(); bitmap.recycle(); } } }}
阅读全文
0 0
- osmdroid API解读(四)
- osmdroid API解读(一)
- osmdroid API解读(二)
- osmdroid API解读(三)
- osmdroid API解读(五)
- osmdroid API解读(六)
- osmdroid API解读(七)
- osmdroid API解读(八)
- osmdroid API解读(九)
- osmdroid API解读(十)
- osmdroid API解读(十一)
- osmdroid API解读(十二)
- osmdroid API解读(十三)
- osmdroid API解读(十四)
- osmdroid API解读(十五)
- 四、关于osmdroid地图源的疑问
- 实时开发框架Meteor API解读系列<四>Server connections
- 《代码大全》解读(四)
- NOIP模拟(20171024)T1 Graph
- 10月24日 c语言 用指针方法对10个整数按由大到小顺序排列
- PHP的引用传址和赋值传值以及unset()
- 如何下载windows镜像
- 关于异常处理的问题
- osmdroid API解读(四)
- js作用域
- Okhttp3 简单单例封装
- 还是不想就此而终
- JAVA SE基础知识(一)
- spring事务
- 1023. Have Fun with Numbers (20)
- 我男朋友是个程序员# 3 之《备份引发的血案》
- 10月24日 c语言 将数组a中的n个整数按相反顺序存放