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;
}
}