osmdroid API解读(四)
2017-10-24 19:09
323 查看
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(); } } } }
相关文章推荐
- osmdroid API解读(一)
- osmdroid API解读(三)
- osmdroid API解读(二)
- osmdroid API解读(十三)
- osmdroid API解读(八)
- osmdroid API解读(十一)
- osmdroid API解读(九)
- osmdroid API解读(五)
- Android开发之Dialog的三种列表显示(解读谷歌官方API)
- FastDFS的配置、部署与API使用解读(2)以字节方式上传文件的客户端代码
- 解读VC++编程中的文件操作API和CFile类
- Node.js API 初解读(一)
- FastDFS的配置、部署与API使用解读(4)FastDFS配置详解之Client配置
- Google Map API使用详解(六)——Google Map API Key的解读和使用技巧
- 解读官方Android MediaPlayer API(2)
- FastDFS的配置、部署与API使用解读(2)以字节方式上传文件的客户端代码
- FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块
- FastDFS的配置、部署与API使用解读(2)以字节方式上传文件的客户端代码
- ZigBee学习之7——OSAL(操作系统抽象层)API解读
- FastDFS的配置、部署与API使用解读(3)以流的方式上传文件的客户端代码