package edu.hebtu.movingcampus.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.ref.SoftReference; import java.util.LinkedHashMap; import org.apache.http.util.EncodingUtils; import android.annotation.SuppressLint; import android.content.Context; import android.database.Cursor; import android.os.Build; import android.os.Environment; import edu.hebtu.movingcampus.AppInfo; import edu.hebtu.movingcampus.config.Configs; import edu.hebtu.movingcampus.config.Constants; import edu.hebtu.movingcampus.db.DBHelper; import edu.hebtu.movingcampus.db.RequestCacheColumn; //整个调用方法就是异步,这里不需要异步 public class RequestCacheUtil { private static final String TAG = "RequestCacheUtil"; private static LinkedHashMap<String, SoftReference<String>> RequestCache = new LinkedHashMap<String, SoftReference<String>>( 20); // [start] 公有方法 /** * it is a get way to visit a websit * @param context * @param RequestUrl * @param source_type * @param content_type * @param UseCache * @return */ public static String getRequestContentByGet(Context context, String RequestUrl, String source_type, String content_type, boolean UseCache) { DBHelper dbHelper = DBHelper.getInstance(context); String md5 = MD5.encode(RequestUrl); // 缓存目录 if (!CommonUtil.sdCardIsAvailable())/* true 为可用 */{ String cachePath = AppInfo.cacheDir + "/" + md5; // data里的缓存 return getCacheRequestByGet(context, RequestUrl, cachePath, source_type, content_type, dbHelper, UseCache); } else { String imagePath = AppInfo.cacheDir + File.separator + md5; // sd卡 return getCacheRequestByGet(context, RequestUrl, imagePath, source_type, content_type, dbHelper, UseCache); } } /** * it is a post way to visit a websit * @param context * @param RequestUrl * @param source_type * @param content_type * @param UseCache * @return */ public static String getRequestContentByPost(Context context, String RequestUrl, String source_type, String content_type, boolean UseCache) { DBHelper dbHelper = DBHelper.getInstance(context); String md5 = MD5.encode(RequestUrl); // 缓存目录 if (!CommonUtil.sdCardIsAvailable())/* true 为可用 */{ String cachePath = context.getCacheDir().getAbsolutePath() + "/" + md5; // data里的缓存 return getCacheRequestByPost(context, RequestUrl, cachePath, source_type, content_type, dbHelper, UseCache); } else { String imagePath = getExternalCacheDir(context) + File.separator + md5; // sd卡 return getCacheRequestByPost(context, RequestUrl, imagePath, source_type, content_type, dbHelper, UseCache); } } // [end] // [start] 私有方法 /** * 获得程序在sd|root上的cahce目录 * * @param context * The context to use * @return The external cache dir */ //TODO not used @SuppressLint("NewApi") public static File getExternalCacheDir(Context context) { // android 2.2 以后才支持的特性 if (hasExternalCacheDir()) { if(context.getExternalCacheDir()!=null) return new File(context.getExternalCacheDir().getPath() + File.separator + "request"); }else{ // Before Froyo we need to construct the external cache dir ourselves // 2.2以前我们需要自己构造 final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/request/"; if(Environment.getExternalStorageDirectory()!=null) return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir); } return new File(context.getCacheDir().getPath() + File.separator + "request"); } private static boolean hasExternalCacheDir() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; } /** * it is a get method that used to connect to web * @param context * @param requestUrl * @param requestPath * @param source_type * @param content_type * @param dbHelper * @param useCache * @return */ private static String getCacheRequestByGet(Context context, String requestUrl, String requestPath, String source_type, String content_type, DBHelper dbHelper, boolean useCache) { String result = ""; if (useCache) { result = getStringFromSoftReference(requestUrl); if (!result.equals(null) && !result.equals("")) { return result; } result = getStringFromLocal(requestPath, requestUrl, dbHelper); if (!result.equals(null) && !result.equals("")) { putStringForSoftReference(requestUrl, result); return result; } } // not using cache or cannot find any cache file in sqlite or localfile // , getStringFromWeb instead result = getStringFromWebByGet(context, requestPath, requestUrl, source_type, content_type, dbHelper); return result; } /** * it is a post method that used to connect to web * @param context * @param requestUrl * @param requestPath * @param source_type * @param content_type * @param dbHelper * @param useCache * @return */ private static String getCacheRequestByPost(Context context, String requestUrl, String requestPath, String source_type, String content_type, DBHelper dbHelper, boolean useCache) { String result = ""; if (useCache) { result = getStringFromSoftReference(requestUrl); if (!result.equals(null) && !result.equals("")) { return result; } result = getStringFromLocal(requestPath, requestUrl, dbHelper); if (!result.equals(null) && !result.equals("")) { putStringForSoftReference(requestUrl, result); return result; } } // not using cache or cannot find any cache file in sqlite or localfile // , getStringFromWeb instead result = getStringFromWebByPost(context, requestPath, requestUrl, source_type, content_type, dbHelper); return result; } private static void putStringForSoftReference(String requestUrl, String result) { SoftReference<String> referece = new SoftReference<String>(result); RequestCache.put(requestUrl, referece); } /** * to visit a service by post method * @param context * @param requestPath * @param requestUrl * @param source_type * @param content_type * @param dbHelper * @return */ private static String getStringFromWebByGet(Context context, String requestPath, String requestUrl, String source_type, String content_type, DBHelper dbHelper) { String result = ""; try { result = HttpUtils.getByHttpClient(context, requestUrl); if (result.equals(null) || result.equals("")) { return result; } // 更新数据库 Cursor cursor = getStringFromDB(requestUrl, dbHelper); updateDB(cursor, requestUrl, source_type, content_type, dbHelper); saveFileByRequestPath(requestPath, result); putStringForSoftReference(requestUrl, result); if (cursor != null) cursor.close(); } catch (Exception e) { e.printStackTrace(); } return result; } /** * to visit a service by post method * @param context * @param requestPath * @param requestUrl * @param source_type * @param content_type * @param dbHelper * @return the result of request of web */ private static String getStringFromWebByPost(Context context, String requestPath, String requestUrl, String source_type, String content_type, DBHelper dbHelper) { String result = ""; try { result = HttpUtils.postByHttpClient(context, requestUrl); if (result.equals(null) || result.equals("")) { return result; } // 更新数据库 Cursor cursor = getStringFromDB(requestUrl, dbHelper); updateDB(cursor, requestUrl, source_type, content_type, dbHelper); saveFileByRequestPath(requestPath, result); putStringForSoftReference(requestUrl, result); if (cursor != null) cursor.close(); } catch (Exception e) { e.printStackTrace(); } return result; } private static void saveFileByRequestPath(String requestPath, String result) { deleteFileFromLocal(requestPath); saveFileForLocal(requestPath, result); } private static void saveFileForLocal(String requestPath, String result) { File file = new File(requestPath); if (!file.exists()) { try { File parentFile = file.getParentFile(); if (!parentFile.exists()) { parentFile.mkdirs(); } file.createNewFile(); FileOutputStream fout = new FileOutputStream(file); byte[] buffer = result.getBytes(); fout.write(buffer); fout.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } private static void updateDB(Cursor cursor, String requestUrl, String source_type, String content_type, DBHelper dbHelper) { if (cursor != null && cursor.moveToFirst()) { // 更新 int id = cursor.getInt(cursor .getColumnIndex(RequestCacheColumn._ID)); long timestamp = System.currentTimeMillis(); String SQL = "update " + RequestCacheColumn.TABLE_NAME + " set " + RequestCacheColumn.Timestamp + "=" + timestamp + " where " + RequestCacheColumn._ID + "=" + id; dbHelper.ExecSQL(SQL); } else { // 添加 String SQL = "insert into " + RequestCacheColumn.TABLE_NAME + "(" + RequestCacheColumn.URL + "," + RequestCacheColumn.SOURCE_TYPE + "," + RequestCacheColumn.Content_type + "," + RequestCacheColumn.Timestamp + ") values('" + requestUrl + "','" + source_type + "','" + content_type + "','" + System.currentTimeMillis() + "')"; dbHelper.ExecSQL(SQL); } } private static String getStringFromSoftReference(String requestUrl) { if (RequestCache.containsKey(requestUrl)) { SoftReference<String> reference = RequestCache.get(requestUrl); String result = (String) reference.get(); if (result != null && !result.equals("")) { return result; } } return ""; } private static String getStringFromLocal(String requestPath, String requestUrl, DBHelper dbHelper) { String result = ""; Cursor cursor = getStringFromDB(requestUrl, dbHelper); if (cursor != null && cursor.moveToFirst()) { Long timestamp = cursor.getLong(cursor .getColumnIndex(RequestCacheColumn.Timestamp)); String strContentType = cursor.getString(cursor .getColumnIndex(RequestCacheColumn.Content_type)); long span = getSpanTimeFromConfigs(strContentType); long nowTime = System.currentTimeMillis(); if ((nowTime - timestamp) > span * 60 * 1000) { // 过期 deleteFileFromLocal(requestPath); } else { // 没过期 result = getFileFromLocal(requestPath); } cursor.close(); } return result; } /** * 从db中查找数据 * * @param requestUrl * @param dbHelper * @return */ private static Cursor getStringFromDB(String requestUrl, DBHelper dbHelper) { String SQL = "select * from " + RequestCacheColumn.TABLE_NAME + " where " + RequestCacheColumn.URL + "='" + requestUrl + "'"; return dbHelper.rawQuery(SQL, new String[] {}); } private static String getFileFromLocal(String requestPath) { // TODO Auto-generated method stub File file = new File(requestPath); String result = ""; if (file.exists()) { FileInputStream fileIn; try { fileIn = new FileInputStream(file); int length = fileIn.available(); byte[] buffer = new byte[length]; fileIn.read(buffer); result = EncodingUtils.getString(buffer, "UTF-8"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } return ""; } private static void deleteFileFromLocal(String requestPath) { // TODO Auto-generated method stub File file = new File(requestPath); if (file.exists()) { file.delete(); } } /** * 根据类型获取缓存时间 * * @param str * @return */ private static long getSpanTimeFromConfigs(String str) { long span = 0; if (str.equals(Constants.DBContentType.Content_list)) { span = Configs.Content_ListCacheTime; } else if (str.equals(Constants.DBContentType.Content_content)) { span = Configs.Content_ContentCacheTime; } else { span = Configs.Content_DefaultCacheTime; } return span; } // [end] }