网络图片的本地缓存优化策略

游戏机顶盒市场项目已经实现,摘抄至此,作为记录:

一 思想:

// ===========================================================
 // 市场端图片缓存策略:
 //第一种:图标小图片
 // 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;
	}

 

三、没了

posted @ 2013-06-28 17:25  Liu Siyuan  阅读(370)  评论(0编辑  收藏  举报