編輯:關於Android編程
這些類的繼承關系如下圖所示:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20140711/20140711090242214.jpg" alt="\">
如同文件緩存一樣,內存緩存涉及的接口也有兩個:MemoryCacheAware 和MemoryCache,其中MemoryCache只是簡單的繼承了MemoryCacheAware並沒有聲明其他的方法。MemoryCacheAware接口的方法如下:
@Deprecated public interface MemoryCacheAware{ /** *根據key值把value放入緩存 * @return 如果放入緩存成功的話就返回true,反之返回false */ boolean put(K key, V value); /**根據key從緩存中獲取數據,沒有相關數據則返回null*/ V get(K key); /** 根據key從緩存中刪除數據*/ void remove(K key); /** 返回緩存中所有的key */ Collection keys(); /** 清空緩存*/ void clear(); }
BaseMemoryCache:
該類是一個抽象類,提供了一個map,用來緩存Bitmap的弱引用:
private final Map> softMap = Collections.synchronizedMap(new HashMap >());
/**根據value創建一個弱引用對象,該類為抽象類,供子類實現 */ protected abstract ReferencecreateReference(Bitmap value); @Override public boolean put(String key, Bitmap value) { softMap.put(key, createReference(value)); return true; }
LimitedMemoryCache:
該類為抽象類,繼承了BaseMemoryChache;對緩存進行了兩個限制:1) 限制每一個緩存圖片的最大值:用sizeLimit來作為標致,對大於sizeLimit大小的bitmap對象,調用父類的put方法保存bitmap的弱引用。否則在保存弱引用的同時,把Bitmap對象的強引用用類型為LinkedList變量hardCache緩存起來,
2) 同樣用sizeLimit來限制整個緩存的大小。對是否超出緩存大小的限制在put方法被調用的時候會做判斷,如果緩存大小超出限制就從LinkedList中刪除對應的bitmap對象,具體的刪除策略有該類的抽象方法remoeNext()提供,具體的在子父類中實現(比如有的是刪除最大的那個bitMap,以及根據FIFO算法刪除等等),這是典型的模板方法模式的應用。具體的模板方法為romoveNext()和getSize()由相應的子類實現。
注意put方法的返回值,當要加入的bitMap的大小超過sizeLimit的就返回false,否則返回true(在子類中調用該put方法,返回true說明對緩存進行了對應的刪除操作)
private final ListhardCache = Collections.synchronizedList(new LinkedList ());//hardCache只是在此類中只是用來對緩存是否超過sizeLimit做判斷。 //bitMap放入緩存 @Override public boolean put(String key, Bitmap value) { boolean putSuccessfully = false; // Try to add value to hard cache //getSize方法為抽象方法,由子類實現 int valueSize = getSize(value); int sizeLimit = this.sizeLimit; int curCacheSize = cacheSize.get(); //當bitmap的大小小於sizeLimit的大小時 if (valueSize < sizeLimit) { //對緩存進行刪除操作,使之不超過siezeLimit的限制,。我們 while (curCacheSize + valueSize > sizeLimit) { Bitmap removedValue = removeNext();//removeNext()為抽象方法,由不同的子類提供不同的刪除策略 if (hardCache.remove(removedValue)) { curCacheSize = cacheSize.addAndGet(-getSize(removedValue)); } } //放入緩存 hardCache.add(value); //設置緩存大小 cacheSize.addAndGet(valueSize); putSuccessfully = true; } //獲取bitMap的大小 protected abstract int getSize(Bitmap value); //模板方法,由相應的子類來實現具體的刪除策略 protected abstract Bitmap removeNext();
該類為LimitedMemoryCache的子類,該類的目的是當超出緩存大小限制的時候刪除緩存中最大的那個bitmap對象。該類實現了父類的兩個抽象方法:getSize()和removeNext()來獲取某個bitmap的大小和刪除最大的那個bitMap對象。
實現的原理: 該類添加了一個map變量,該map的key用來保存bitMap對象,而對應的value則保存bitmap的大小。
private final MapvalueSizes = Collections.synchronizedMap(new HashMap ());
/** * 循環遍歷valueSizes,並獲取最大的那個bitmap,並且從map中刪除之 返回的Bimmap對象交給父類的hardCache刪除 */ @Override protected Bitmap removeNext() { Integer maxSize = null; Bitmap largestValue = null; Set> entries = valueSizes.entrySet(); synchronized (valueSizes) { for (Entry entry : entries) { if (largestValue == null) { largestValue = entry.getKey(); maxSize = entry.getValue(); } else { Integer size = entry.getValue(); if (size > maxSize) { maxSize = size; largestValue = entry.getKey(); } } } } //執行刪除稻作 valueSizes.remove(largestValue); return largestValue; } //獲取getSize的方法 @Override protected int getSize(Bitmap value) { return value.getRowBytes() * value.getHeight(); } @Override protected Reference createReference(Bitmap value) { return new WeakReference (value); }
刪除操作執行時機:調用父類put方法是執行
@Override public boolean put(String key, Bitmap value) { if (super.put(key, value)) {//如果父類的方法為空,說明緩存的大小沒有超出限制 valueSizes.put(value, getSize(value)); return true; } else {//緩存的大小超出限制 return false; } }
FIFOLimitedMemoryCache :
LimitedMomroyCache的子類,當當前緩存的大小超出限制的時候,會根據FIFO(先進先出)算法刪除響應的bitmap緩存對象。該類用LinkedList來作為FIFO的實現方式,當超出緩存大小的時候,調用removeNext()來從緩存中刪除首先加入進來的bitmap對象。相應的方法如下:
實現原理:提供了一個LinkedList來保存bitmap對象
private final Listqueue = Collections.synchronizedList(new LinkedList ());
@Override protected Bitmap removeNext() { return queue.remove(0); } @Override protected Reference刪除操作執行時機:調用父類put方法是執行createReference(Bitmap value) { return new WeakReference (value); } @Override protected int getSize(Bitmap value) { return value.getRowBytes() * value.getHeight(); }
@Override public boolean put(String key, Bitmap value) { if (super.put(key, value)) {//如果緩存沒有超出范圍 queue.add(value);//把bitmap放入隊列 return true; } else {//緩存超出范圍 return false; } }
LRULimitedMemoryCache:
LimitedMemoryCache的子類,最近最久未使用緩存,當緩存大小超過sizeLimit限制的時候,就從緩存中刪除最近最久未使用的bitmap緩存對象。實現原理:提供了一個LinkedHashMap來保存對象,實現LRU的效果
/** Cache providing Least-Recently-Used logic */ private final Map具體的removeNext()方法實現:lruCache = Collections.synchronizedMap(new LinkedHashMap (INITIAL_CAPACITY, LOAD_FACTOR, true));
@Override protected Bitmap removeNext() { return queue.remove(0); } @Override protected ReferencecreateReference(Bitmap value) { return new WeakReference (value); } @Override protected int getSize(Bitmap value) { return value.getRowBytes() * value.getHeight(); }
@Override public boolean put(String key, Bitmap value) { if (super.put(key, value)) {//如果緩存沒有超出范圍 queue.add(value);//把bitmap放入隊列 return true; } else {//緩存超出范圍 return false; } }
UsingFreqLimitedMemoryCache:
LimitedMemoryCache的子類,當緩存大小超出sizelimit的時候對最久未使用的bitmap對象進行刪除(也就是說對使用次數最少的那個bitmap進行刪除操作)
實現原理:提供了一個hashMap,該map的key保存bitmap對象,而value則保存對應bitmap的使用次數
private final Map當調用get(string key)方法獲取bitmap的時候,該bitmap的使用次數進行+1操作usingCounts = Collections.synchronizedMap(new HashMap ());
@Override public Bitmap get(String key) { Bitmap value = super.get(key); // Increment usage count for value if value is contained in hardCahe if (value != null) { Integer usageCount = usingCounts.get(value); if (usageCount != null) { //使用次數+1 usingCounts.put(value, usageCount + 1); } } return value; }
@Override protected int getSize(Bitmap value) { return value.getRowBytes() * value.getHeight(); } @Override protected Bitmap removeNext() { Integer minUsageCount = null; Bitmap leastUsedValue = null; Set> entries = usingCounts.entrySet(); synchronized (usingCounts) { for (Entry entry : entries) { if (leastUsedValue == null) { leastUsedValue = entry.getKey(); minUsageCount = entry.getValue(); } else { Integer lastValueUsage = entry.getValue(); if (lastValueUsage < minUsageCount) { minUsageCount = lastValueUsage; leastUsedValue = entry.getKey(); } } } } usingCounts.remove(leastUsedValue); return leastUsedValue; } @Override protected Reference createReference(Bitmap value) { return new WeakReference (value); }
@Override public boolean put(String key, Bitmap value) { if (super.put(key, value)) { usingCounts.put(value, 0); return true; } else { return false; } }
LimitedAgeMemoryCache:
對超出時間限制的緩存對象進行刪除,該類的實現畢竟簡單,具體代碼如下:public class LimitedAgeMemoryCache implements MemoryCache { private final MemoryCache cache; private final long maxAge; private final MaploadingDates = Collections.synchronizedMap(new HashMap ()); /** * @param cache Wrapped memory cache * @param maxAge Max object age (in seconds). If object age will exceed this value then it'll be removed from * cache on next treatment (and therefore be reloaded). */ public LimitedAgeMemoryCache(MemoryCache cache, long maxAge) { this.cache = cache; this.maxAge = maxAge * 1000; // to milliseconds } @Override public boolean put(String key, Bitmap value) { boolean putSuccesfully = cache.put(key, value); if (putSuccesfully) { loadingDates.put(key, System.currentTimeMillis()); } return putSuccesfully; } @Override public Bitmap get(String key) { Long loadingDate = loadingDates.get(key); //判斷是否超時 if (loadingDate != null && System.currentTimeMillis() - loadingDate > maxAge) { cache.remove(key); loadingDates.remove(key); } return cache.get(key); } @Override public void remove(String key) { cache.remove(key); loadingDates.remove(key); } @Override public Collection keys() { return cache.keys(); } @Override public void clear() { cache.clear(); loadingDates.clear(); } }
FuzzyKeyMemoryCache:
該緩存的作用就是如果緩存中的有一個key和要加入的keytemp相等,就從緩存中刪除該key指向的bitmap對象,然後把新的key對象加入到緩存中去。具體的邏輯如下:
@Override public boolean put(String key, Bitmap value) { // Search equal key and remove this entry synchronized (cache) { String keyToRemove = null; for (String cacheKey : cache.keys()) { //判斷緩存中對應的key是否存在,存在就刪除 if (keyComparator.compare(key, cacheKey) == 0) { keyToRemove = cacheKey; break; } } if (keyToRemove != null) { cache.remove(keyToRemove); } } return cache.put(key, value); }
@Override public final boolean put(String key, Bitmap value) { synchronized (this) { size += sizeOf(key, value); Bitmap previous = map.put(key, value); if (previous != null) { size -= sizeOf(key, previous); } } //緩存瘦身,把最近最久未使用的bitMap刪除 trimToSize(maxSize); return true; } private void trimToSize(int maxSize) { while (true) { String key; Bitmap value; synchronized (this) { Map.EntrytoEvict = map.entrySet().iterator().next(); if (toEvict == null) { break; } key = toEvict.getKey(); value = toEvict.getValue(); map.remove(key); size -= sizeOf(key, value); } } }
1. 為什麼TCP連接需要心跳? 因為運營商有一個NAT超時:因為IP v4的IP量有限,運營商分配給手機終端的IP是運營商內網的IP,手機要連接Internet,就需要
(一)概述Android 3.0後引入的一個UI控件——ViewPager(視圖滑動切換工具),實在想不到 如何來稱呼這個控件,他的大概功能:通過
果殼網旗下在行在微信公眾號上線了一款付費語音問答新產品——分答。 用戶在分答上可以自我介紹或描述擅長的領域,設置付費問答
現在很多安全類的軟件,比如360手機助手,百度手機助手等等,都有一個懸浮窗,可以飄浮在桌面上,方便用戶使用一些常用的操作。今天這篇文章,就是介紹如何實現桌面懸浮窗效果的。