package com.smartandroid.sa.aysnc; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import android.content.Context; /** * <p> * Cached AsyncTask �����첽���� * <p> * ����Ҫ���ڻ�ȡ�������ݣ�����һ������ʱ�䣬ֻҪδ��ʱ�������ȴӱ��ػ�ȡ��������ʱ�򱾵ػ�ȡʧ��ʱ��ȥ����������ɡ� * <b>ÿ��Task��������Ψһ��ʾ��key��</b>��Ψһ��ʾһ���������񣬲�ͬ��������Բ���һ��������������ʱʱ�䡣 <b> * {@link #CachedTask#Result} ��Ҫ���л�</b>�����ܻ��߲��������Ķ�ȡ���档 * * @author MaTianyu 2014-2-23����8:57:55 */ public abstract class CTask<Params, Progress, Result extends Serializable> extends ASafeTask<Params, Progress, Result> { private static final String TAG = CTask.class.getSimpleName(); private static final String DEFAULT_PATH = "/cachedtask"; private long expiredTime = 0; private static String cachePath; private String key; private static ConcurrentHashMap<String, Long> cachedTimeMap = new ConcurrentHashMap<String, Long>(); public static void cleanCacheFiles(Context context) { cachedTimeMap.clear(); cachePath = context.getFilesDir().getAbsolutePath() + DEFAULT_PATH; File file = new File(cachePath); final File[] fileList = file.listFiles(); if (fileList != null) { TaskExecutor.start(new Runnable() { @Override public void run() { for (File f : fileList) { if (f.isFile()) f.delete(); } } }); } } public static void removeKeyValue(String key) { cachedTimeMap.remove(key); } /** * @param context * app context * @param key * identify label, each single cachedtask should not be the same. * @param cacheTime * expired time * @param unit * if timeunit is null, see cacheTime as millisecond. */ public CTask(Context context, String key, long cacheTime, TimeUnit unit) { if (context == null) throw new RuntimeException( "CachedTask Initialized Must has Context"); cachePath = context.getFilesDir().getAbsolutePath() + DEFAULT_PATH; if (key == null) throw new RuntimeException("CachedTask Must Has Key for Search "); this.key = key; if (unit != null) expiredTime = unit.toMillis(cacheTime); else expiredTime = cacheTime; } protected abstract Result doConnectNetwork(Params... params) throws Exception; @Override protected final Result doInBackgroundSafely(Params... params) throws Exception { Result res = null; try { Long time = cachedTimeMap.get(key); long lastTime = time == null ? 0 : time; if (System.currentTimeMillis() - lastTime >= expiredTime) { res = doConnectNetwork(params); if (res != null) { if (Log.isPrint) Log.d(TAG, "doConnectNetwork: sucess"); cachedTimeMap.put(key, System.currentTimeMillis()); saveResultToCache(res); } else { if (Log.isPrint) Log.d(TAG, "doConnectNetwork: false"); res = getResultFromCache(); } } else { res = getResultFromCache(); if (res == null) { res = doConnectNetwork(params); if (res != null) { if (Log.isPrint) Log.d(TAG, "doConnectNetwork: sucess"); cachedTimeMap.put(key, System.currentTimeMillis()); saveResultToCache(res); } else { if (Log.isPrint) Log.d(TAG, "doConnectNetwork: false"); } } } } catch (Exception e) { e.printStackTrace(); } return res; } @SuppressWarnings("unchecked") private Result getResultFromCache() { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream(new File(cachePath, key))); Object obj = ois.readObject(); if (obj != null) { if (Log.isPrint) Log.i(TAG, key + " read from cache: " + obj); return (Result) obj; } } catch (Exception e) { e.printStackTrace(); } finally { if (ois != null) try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } if (Log.isPrint) Log.e(TAG, "read ResultFromCache: fail "); return null; } private boolean saveResultToCache(Result res) { ObjectOutputStream oos = null; try { File dir = new File(cachePath); if (!dir.exists()) dir.mkdirs(); oos = new ObjectOutputStream(new FileOutputStream( new File(dir, key))); oos.writeObject(res); if (Log.isPrint) Log.i(TAG, key + " saveto cache: " + res); return true; } catch (Exception e) { e.printStackTrace(); } finally { if (oos != null) try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } if (Log.isPrint) Log.e(TAG, "save Result To Cache: fail"); return false; } }