Back to project page Alfred4Android.
The source code is released under:
Apache License
If you think the Android project Alfred4Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.toraleap.collimator.util; /*ww w. java 2 s.c om*/ import java.lang.ref.SoftReference; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import android.os.Handler; import android.os.Message; import android.util.Log; /** * ????????????????????????????? request ???????????????????? * @author uestc.Mobius <mobius@toraleap.com> * @version 2010.1104 * * @param <K> ?????????? * @param <V> ????????? */ public abstract class SoftCache<K, V> { private static final int MESSAGE_FIRST = 200; public static final int MESSAGE_CACHE_GOT = MESSAGE_FIRST + 1; public static final int MESSAGE_QUEUE_FINISHED = MESSAGE_FIRST + 2; private final ConcurrentHashMap<K, SoftReference<V>> cache = new ConcurrentHashMap<K, SoftReference<V>>(); private final LinkedBlockingQueue<K> queue = new LinkedBlockingQueue<K>(); private final SoftReference<V> loadingHolder = new SoftReference<V>(null); private final Handler callback; private final Thread thread = new Thread() { public void run() { K key; while (true) { try { key = queue.take(); requestAndCache(key); if (!isInterrupted()) { sendHandlerMessage(MESSAGE_CACHE_GOT, 0, 0, key); if (queue.size() == 0) sendHandlerMessage(MESSAGE_QUEUE_FINISHED, 0, 0, null); } else { clearQueue(); } } catch (InterruptedException e) { e.printStackTrace(); clearQueue(); } } } }; /** * ????????????????????? * @param callback ???????????? Handler */ public SoftCache(Handler callback) { this.callback = callback; thread.setDaemon(true); thread.start(); } /** * ????????????????????????????????????????????????? ???? ?????????????????????????????????????????????????????????????? Handler ???? MESSAGE_CACHE_GOT ??????????????????????????? Handler ???? MESSAGE_QUEUE_FINISHED ?????????????????????? getDefault ??????? * @param key ????????? * @return ????????????????? */ public V get(K key) { SoftReference<V> ref = cache.get(key); // ????????????????????? if (ref == null) { offerRequest(key); return getDefault(); } // ???????????? if (ref == loadingHolder) { return getDefault(); } V value = ref.get(); // ????????????????????? if (value == null) { offerRequest(key); return getDefault(); } // ????????????? return value; } /** * ???????????????????????????????????????? Handler ???? MESSAGE_CACHE_GOT ??????????????? MESSAGE_QUEUE_FINISHED ????? */ public void interrupt() { thread.interrupt(); } /** * ????????????????????????????????????????????????????????? null???????????????????? * @param key ?????????? * @return ??????????????? null */ V getCache(K key) { SoftReference<V> ref = cache.get(key); if (ref == null) return null; return ref.get(); } /** * ??????????????????????????????????????? * @param key ????? * @param value ??????????? * @return ??????????? */ V putCache(K key, V value) { if (value == null) return null; cache.put(key, new SoftReference<V>(value)); return value; } /** * ???????????????????????????????????????????????????????????????????????????? * @param key ?????????? * @return ?????? */ V requestAndCache(K key) { V value = getCache(key); // ??????????????????? if (value == null) { return putCache(key, request(key)); } // ????????????? return value; } /** * ?????????????????????? * @param key ?????????? */ private void offerRequest(K key) { cache.put(key, loadingHolder); queue.offer(key); if (getMaxQueueLength() > 0 && queue.size() > getMaxQueueLength()) { cache.remove(queue.remove()); } } /** * ??????????????????????????????????? */ private void clearQueue() { while (true) { K key = queue.poll(); if (key == null) break; cache.remove(key); } } /** * ??????????????????????? * @param what ??????? * @param arg1 ???????1 (????????????) * @param arg2 ???????2 (????????????) * @param obj ?????????? (????????????) */ private void sendHandlerMessage(int what, int arg1, int arg2, Object obj) { if (null != callback) { Message msg = Message.obtain(); msg.what = what; msg.arg1 = arg1; msg.arg2 = arg2; msg.obj = obj; callback.sendMessage(msg); } } /** * ??????????????????????????????????? null?? * @return ??? null ?????? */ V getDefault() { return null; } /** * ????????????????????????????????????????????????????????????????????????????(-1)?? * @return */ int getMaxQueueLength() { return -1; } /** * ????????????????????????????????????????????????? * @param key ????????? * @return ?????????? */ abstract V request(K key); }