网络图片的本地缓存优化策略
游戏机顶盒市场项目已经实现,摘抄至此,作为记录:
一 思想:
// ===========================================================
// 市场端图片缓存策略:
//第一种:图标小图片
// 1、路径在手机空间包名路径下cache文件夹,设定大小为10M
// 2、每次加载图片时做以下操作:
// a、尝试获取本地图片,若有图片,则返回图片,修改其最后使用时间,若本地不存在,则去网络获取
// b、从服务器返回的图片,直接下载到缓存路径(增加失败重试机制)
// 3、每次启动时,检查缓存大小,若超过10M,则将文件按照最后修改时间排序,删掉最近不常用的一半图片
//第二种:广告、专题、游戏界面等大图片
// 1、路径在Sdcard/本应用专属路径下cache文件夹,设定大小为10M
// 2、每次加载图片时做以下操作:
// a、尝试获取本地图片,若有图片,则返回推按,修改其最后使用时间,若本地不存在,则去网络获取
// b、从服务器返回的图片,直接下载到缓存路径(增加失败重试机制)
// 3、每次启动时,检查缓存大小,若超过20M,则将文件按照最后修改时间排序,删掉最近不常用的一半图片
二 代码:
1.启动时检查本地缓存,在子线程中调用
/** * clear cache * check cache space delete half of it * set cache space 10M * @param ctx * @throws IOException */ public static void clearLargeCache(Context ctx) throws IOException { File cacheFile = ctx.getCacheDir(); File[] files = cacheFile.listFiles(); if (dirSize(files) >= 30 * 1024 * 1024) { Arrays.sort(files, new Comparator<File>() { @Override public int compare(File object1, File object2) { File file1 = (File) object1; File file2 = (File) object2; long diff = file1.lastModified() - file2.lastModified(); if (diff > 0) return 1; else if (diff == 0) return 0; else return -1; } }); int count = files.length / 2; for (int i = count; i >= 0; i--) { if (!files[i].isDirectory()) files[i].delete(); } } }
/** * Return the size of a directory in bytes * @param fileList * @return */ private static long dirSize(File[] fileList) { long result = 0; for (int i = 0; i < fileList.length; i++) { if (!fileList[i].isDirectory()) { // Sum the file size in bytes result += fileList[i].length(); } } Log.d("MyTag", "Cache size(K) =" + result / 1024); return result; }
2、获取图片
/** * 获取图片并缓存 * @param ctx * @param url * @return * @throws IOException */ public static Drawable getDrawableFromCache(Context ctx, String url) throws IOException { if (url == null || url.equals("")) return null; String urlPath = ""; Uri uri = null; if (url.contains("http")) urlPath = url; else urlPath = Constants.SERVER_ICON_URL + url; File cacheFile = ctx.getCacheDir(); File file = new File(cacheFile, MD5.toMD5(urlPath)); try { if (file.exists()) { hitCount++; if ((hitCount % 100) == 0) Log.d("MyTag", "HitCount = " + hitCount); uri = Uri.fromFile(file); } else { Log.d("MyTag", "Down url = " + urlPath); for(int i = 0; uri == null && i < 3; i ++) { uri = downloadImageFile(file, urlPath); } if(uri == null) return null; } } catch (Exception ex) { Log.d("MyTag", "getDrawableFromCache error = " + ex.getMessage()); ex.printStackTrace(); } finally { if (file.length() < 10) { file.delete(); return null; } else { long newModifiedTime = System.currentTimeMillis(); file.setLastModified(newModifiedTime); } } return Drawable.createFromStream(ctx.getContentResolver() .openInputStream(uri), null); }
/** * 下载文件并返回文件的Uri * @param file * @param urlPath * @return */ private static Uri downloadImageFile(File file, String urlPath) { try { FileOutputStream outStream = new FileOutputStream(file); HttpURLConnection conn = (HttpURLConnection) new URL(urlPath) .openConnection(); conn.setConnectTimeout(Constants.HTTP_SO_TIMEOUT); conn.setRequestMethod("GET"); if (conn.getResponseCode() == 200) { InputStream inStream = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } outStream.close(); inStream.close(); return Uri.fromFile(file); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }
三、没了