The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .gitignore
├── AsimpleCacheDemo
    ├── .classpath
    ├── .project
    ├── .settings
    │   ├── org.eclipse.core.resources.prefs
    │   └── org.eclipse.jdt.core.prefs
    ├── ASimpleCache
    │   └── org
    │   │   └── afinal
    │   │       └── simplecache
    │   │           └── ACache.java
    ├── AndroidManifest.xml
    ├── bin
    │   └── AndroidManifest.xml
    ├── gen
    │   └── com
    │   │   └── yangfuhai
    │   │       └── asimplecachedemo
    │   │           ├── BuildConfig.java
    │   │           └── R.java
    ├── ic_launcher-web.png
    ├── proguard-project.txt
    ├── project.properties
    ├── res
    │   ├── drawable
    │   │   ├── ic_launcher.png
    │   │   └── img_test.png
    │   ├── layout
    │   │   ├── activity_about.xml
    │   │   ├── activity_main.xml
    │   │   ├── activity_save_bitmap.xml
    │   │   ├── activity_save_drawable.xml
    │   │   ├── activity_save_file.xml
    │   │   ├── activity_save_jsonarray.xml
    │   │   ├── activity_save_jsonobject.xml
    │   │   ├── activity_save_object.xml
    │   │   └── activity_save_string.xml
    │   ├── menu
    │   │   └── activity_save_jsonarray.xml
    │   └── values
    │   │   ├── strings.xml
    │   │   └── styles.xml
    └── src
    │   └── com
    │       └── yangfuhai
    │           └── asimplecachedemo
    │               ├── AboutActivity.java
    │               ├── MainActivity.java
    │               ├── SaveBitmapActivity.java
    │               ├── SaveDrawableActivity.java
    │               ├── SaveJsonArrayActivity.java
    │               ├── SaveJsonObjectActivity.java
    │               ├── SaveMediaActivity.java
    │               ├── SaveObjectActivity.java
    │               ├── SaveStringActivity.java
    │               └── beans
    │                   └── UserBean.java
├── LICENSE
├── README.md
└── source
    └── src
        └── org
            └── afinal
                └── simplecache
                    └── ACache.java


/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | 
3 | # Package Files #
4 | *.jar
5 | *.war
6 | *.ear
7 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/.classpath:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <classpath>
 3 | 	<classpathentry kind="src" path="ASimpleCache"/>
 4 | 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 5 | 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 6 | 	<classpathentry kind="src" path="src"/>
 7 | 	<classpathentry kind="src" path="gen"/>
 8 | 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
 9 | 	<classpathentry kind="output" path="bin/classes"/>
10 | </classpath>
11 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/.project:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <projectDescription>
 3 | 	<name>AsimpleCacheDemo</name>
 4 | 	<comment></comment>
 5 | 	<projects>
 6 | 	</projects>
 7 | 	<buildSpec>
 8 | 		<buildCommand>
 9 | 			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
10 | 			<arguments>
11 | 			</arguments>
12 | 		</buildCommand>
13 | 		<buildCommand>
14 | 			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
15 | 			<arguments>
16 | 			</arguments>
17 | 		</buildCommand>
18 | 		<buildCommand>
19 | 			<name>org.eclipse.jdt.core.javabuilder</name>
20 | 			<arguments>
21 | 			</arguments>
22 | 		</buildCommand>
23 | 		<buildCommand>
24 | 			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
25 | 			<arguments>
26 | 			</arguments>
27 | 		</buildCommand>
28 | 	</buildSpec>
29 | 	<natures>
30 | 		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
31 | 		<nature>org.eclipse.jdt.core.javanature</nature>
32 | 	</natures>
33 | </projectDescription>
34 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/<project>=UTF-8
3 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
3 | org.eclipse.jdt.core.compiler.compliance=1.6
4 | org.eclipse.jdt.core.compiler.source=1.6
5 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/ASimpleCache/org/afinal/simplecache/ACache.java:
--------------------------------------------------------------------------------
  1 | /**
  2 |  * Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com).
  3 |  *
  4 |  * Licensed under the Apache License, Version 2.0 (the "License");
  5 |  * you may not use this file except in compliance with the License.
  6 |  * You may obtain a copy of the License at
  7 |  *
  8 |  *      http://www.apache.org/licenses/LICENSE-2.0
  9 |  *
 10 |  * Unless required by applicable law or agreed to in writing, software
 11 |  * distributed under the License is distributed on an "AS IS" BASIS,
 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 |  * See the License for the specific language governing permissions and
 14 |  * limitations under the License.
 15 |  */
 16 | package org.afinal.simplecache;
 17 | 
 18 | import java.io.BufferedReader;
 19 | import java.io.BufferedWriter;
 20 | import java.io.ByteArrayInputStream;
 21 | import java.io.ByteArrayOutputStream;
 22 | import java.io.File;
 23 | import java.io.FileInputStream;
 24 | import java.io.FileNotFoundException;
 25 | import java.io.FileOutputStream;
 26 | import java.io.FileReader;
 27 | import java.io.FileWriter;
 28 | import java.io.IOException;
 29 | import java.io.InputStream;
 30 | import java.io.ObjectInputStream;
 31 | import java.io.ObjectOutputStream;
 32 | import java.io.OutputStream;
 33 | import java.io.RandomAccessFile;
 34 | import java.io.Serializable;
 35 | import java.util.Collections;
 36 | import java.util.HashMap;
 37 | import java.util.Map;
 38 | import java.util.Map.Entry;
 39 | import java.util.Set;
 40 | import java.util.concurrent.atomic.AtomicInteger;
 41 | import java.util.concurrent.atomic.AtomicLong;
 42 | 
 43 | import org.json.JSONArray;
 44 | import org.json.JSONObject;
 45 | 
 46 | import android.content.Context;
 47 | import android.graphics.Bitmap;
 48 | import android.graphics.BitmapFactory;
 49 | import android.graphics.Canvas;
 50 | import android.graphics.PixelFormat;
 51 | import android.graphics.drawable.BitmapDrawable;
 52 | import android.graphics.drawable.Drawable;
 53 | 
 54 | /**
 55 |  * @author Michael Yang(www.yangfuhai.com) update at 2013.08.07
 56 |  */
 57 | public class ACache {
 58 | 	public static final int TIME_HOUR = 60 * 60;
 59 | 	public static final int TIME_DAY = TIME_HOUR * 24;
 60 | 	private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb
 61 | 	private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量
 62 | 	private static Map<String, ACache> mInstanceMap = new HashMap<String, ACache>();
 63 | 	private ACacheManager mCache;
 64 | 
 65 | 	public static ACache get(Context ctx) {
 66 | 		return get(ctx, "ACache");
 67 | 	}
 68 | 
 69 | 	public static ACache get(Context ctx, String cacheName) {
 70 | 		File f = new File(ctx.getCacheDir(), cacheName);
 71 | 		return get(f, MAX_SIZE, MAX_COUNT);
 72 | 	}
 73 | 
 74 | 	public static ACache get(File cacheDir) {
 75 | 		return get(cacheDir, MAX_SIZE, MAX_COUNT);
 76 | 	}
 77 | 
 78 | 	public static ACache get(Context ctx, long max_zise, int max_count) {
 79 | 		File f = new File(ctx.getCacheDir(), "ACache");
 80 | 		return get(f, max_zise, max_count);
 81 | 	}
 82 | 
 83 | 	public static ACache get(File cacheDir, long max_zise, int max_count) {
 84 | 		ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());
 85 | 		if (manager == null) {
 86 | 			manager = new ACache(cacheDir, max_zise, max_count);
 87 | 			mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
 88 | 		}
 89 | 		return manager;
 90 | 	}
 91 | 
 92 | 	private static String myPid() {
 93 | 		return "_" + android.os.Process.myPid();
 94 | 	}
 95 | 
 96 | 	private ACache(File cacheDir, long max_size, int max_count) {
 97 | 		if (!cacheDir.exists() && !cacheDir.mkdirs()) {
 98 | 			throw new RuntimeException("can't make dirs in " + cacheDir.getAbsolutePath());
 99 | 		}
100 | 		mCache = new ACacheManager(cacheDir, max_size, max_count);
101 | 	}
102 | 
103 | 	/**
104 | 	 * Provides a means to save a cached file before the data are available.
105 | 	 * Since writing about the file is complete, and its close method is called,
106 | 	 * its contents will be registered in the cache. Example of use:
107 | 	 * 
108 | 	 * ACache cache = new ACache(this) try { OutputStream stream =
109 | 	 * cache.put("myFileName") stream.write("some bytes".getBytes()); // now
110 | 	 * update cache! stream.close(); } catch(FileNotFoundException e){
111 | 	 * e.printStackTrace() }
112 | 	 */
113 | 	class xFileOutputStream extends FileOutputStream {
114 | 		File file;
115 | 
116 | 		public xFileOutputStream(File file) throws FileNotFoundException {
117 | 			super(file);
118 | 			this.file = file;
119 | 		}
120 | 
121 | 		public void close() throws IOException {
122 | 			super.close();
123 | 			mCache.put(file);
124 | 		}
125 | 	}
126 | 
127 | 	// =======================================
128 | 	// ============ String数据 读写 ==============
129 | 	// =======================================
130 | 	/**
131 | 	 * 保存 String数据 到 缓存中
132 | 	 * 
133 | 	 * @param key
134 | 	 *            保存的key
135 | 	 * @param value
136 | 	 *            保存的String数据
137 | 	 */
138 | 	public void put(String key, String value) {
139 | 		File file = mCache.newFile(key);
140 | 		BufferedWriter out = null;
141 | 		try {
142 | 			out = new BufferedWriter(new FileWriter(file), 1024);
143 | 			out.write(value);
144 | 		} catch (IOException e) {
145 | 			e.printStackTrace();
146 | 		} finally {
147 | 			if (out != null) {
148 | 				try {
149 | 					out.flush();
150 | 					out.close();
151 | 				} catch (IOException e) {
152 | 					e.printStackTrace();
153 | 				}
154 | 			}
155 | 			mCache.put(file);
156 | 		}
157 | 	}
158 | 
159 | 	/**
160 | 	 * 保存 String数据 到 缓存中
161 | 	 * 
162 | 	 * @param key
163 | 	 *            保存的key
164 | 	 * @param value
165 | 	 *            保存的String数据
166 | 	 * @param saveTime
167 | 	 *            保存的时间,单位:秒
168 | 	 */
169 | 	public void put(String key, String value, int saveTime) {
170 | 		put(key, Utils.newStringWithDateInfo(saveTime, value));
171 | 	}
172 | 
173 | 	/**
174 | 	 * 读取 String数据
175 | 	 * 
176 | 	 * @param key
177 | 	 * @return String 数据
178 | 	 */
179 | 	public String getAsString(String key) {
180 | 		File file = mCache.get(key);
181 | 		if (!file.exists())
182 | 			return null;
183 | 		boolean removeFile = false;
184 | 		BufferedReader in = null;
185 | 		try {
186 | 			in = new BufferedReader(new FileReader(file));
187 | 			String readString = "";
188 | 			String currentLine;
189 | 			while ((currentLine = in.readLine()) != null) {
190 | 				readString += currentLine;
191 | 			}
192 | 			if (!Utils.isDue(readString)) {
193 | 				return Utils.clearDateInfo(readString);
194 | 			} else {
195 | 				removeFile = true;
196 | 				return null;
197 | 			}
198 | 		} catch (IOException e) {
199 | 			e.printStackTrace();
200 | 			return null;
201 | 		} finally {
202 | 			if (in != null) {
203 | 				try {
204 | 					in.close();
205 | 				} catch (IOException e) {
206 | 					e.printStackTrace();
207 | 				}
208 | 			}
209 | 			if (removeFile)
210 | 				remove(key);
211 | 		}
212 | 	}
213 | 
214 | 	// =======================================
215 | 	// ============= JSONObject 数据 读写 ==============
216 | 	// =======================================
217 | 	/**
218 | 	 * 保存 JSONObject数据 到 缓存中
219 | 	 * 
220 | 	 * @param key
221 | 	 *            保存的key
222 | 	 * @param value
223 | 	 *            保存的JSON数据
224 | 	 */
225 | 	public void put(String key, JSONObject value) {
226 | 		put(key, value.toString());
227 | 	}
228 | 
229 | 	/**
230 | 	 * 保存 JSONObject数据 到 缓存中
231 | 	 * 
232 | 	 * @param key
233 | 	 *            保存的key
234 | 	 * @param value
235 | 	 *            保存的JSONObject数据
236 | 	 * @param saveTime
237 | 	 *            保存的时间,单位:秒
238 | 	 */
239 | 	public void put(String key, JSONObject value, int saveTime) {
240 | 		put(key, value.toString(), saveTime);
241 | 	}
242 | 
243 | 	/**
244 | 	 * 读取JSONObject数据
245 | 	 * 
246 | 	 * @param key
247 | 	 * @return JSONObject数据
248 | 	 */
249 | 	public JSONObject getAsJSONObject(String key) {
250 | 		String JSONString = getAsString(key);
251 | 		try {
252 | 			JSONObject obj = new JSONObject(JSONString);
253 | 			return obj;
254 | 		} catch (Exception e) {
255 | 			e.printStackTrace();
256 | 			return null;
257 | 		}
258 | 	}
259 | 
260 | 	// =======================================
261 | 	// ============ JSONArray 数据 读写 =============
262 | 	// =======================================
263 | 	/**
264 | 	 * 保存 JSONArray数据 到 缓存中
265 | 	 * 
266 | 	 * @param key
267 | 	 *            保存的key
268 | 	 * @param value
269 | 	 *            保存的JSONArray数据
270 | 	 */
271 | 	public void put(String key, JSONArray value) {
272 | 		put(key, value.toString());
273 | 	}
274 | 
275 | 	/**
276 | 	 * 保存 JSONArray数据 到 缓存中
277 | 	 * 
278 | 	 * @param key
279 | 	 *            保存的key
280 | 	 * @param value
281 | 	 *            保存的JSONArray数据
282 | 	 * @param saveTime
283 | 	 *            保存的时间,单位:秒
284 | 	 */
285 | 	public void put(String key, JSONArray value, int saveTime) {
286 | 		put(key, value.toString(), saveTime);
287 | 	}
288 | 
289 | 	/**
290 | 	 * 读取JSONArray数据
291 | 	 * 
292 | 	 * @param key
293 | 	 * @return JSONArray数据
294 | 	 */
295 | 	public JSONArray getAsJSONArray(String key) {
296 | 		String JSONString = getAsString(key);
297 | 		try {
298 | 			JSONArray obj = new JSONArray(JSONString);
299 | 			return obj;
300 | 		} catch (Exception e) {
301 | 			e.printStackTrace();
302 | 			return null;
303 | 		}
304 | 	}
305 | 
306 | 	// =======================================
307 | 	// ============== byte 数据 读写 =============
308 | 	// =======================================
309 | 	/**
310 | 	 * 保存 byte数据 到 缓存中
311 | 	 * 
312 | 	 * @param key
313 | 	 *            保存的key
314 | 	 * @param value
315 | 	 *            保存的数据
316 | 	 */
317 | 	public void put(String key, byte[] value) {
318 | 		File file = mCache.newFile(key);
319 | 		FileOutputStream out = null;
320 | 		try {
321 | 			out = new FileOutputStream(file);
322 | 			out.write(value);
323 | 		} catch (Exception e) {
324 | 			e.printStackTrace();
325 | 		} finally {
326 | 			if (out != null) {
327 | 				try {
328 | 					out.flush();
329 | 					out.close();
330 | 				} catch (IOException e) {
331 | 					e.printStackTrace();
332 | 				}
333 | 			}
334 | 			mCache.put(file);
335 | 		}
336 | 	}
337 | 
338 | 	/**
339 | 	 * Cache for a stream
340 | 	 * 
341 | 	 * @param key
342 | 	 *            the file name.
343 | 	 * @return OutputStream stream for writing data.
344 | 	 * @throws FileNotFoundException
345 | 	 *             if the file can not be created.
346 | 	 */
347 | 	public OutputStream put(String key) throws FileNotFoundException {
348 | 		return new xFileOutputStream(mCache.newFile(key));
349 | 	}
350 | 
351 | 	/**
352 | 	 * 
353 | 	 * @param key
354 | 	 *            the file name.
355 | 	 * @return (InputStream or null) stream previously saved in cache.
356 | 	 * @throws FileNotFoundException
357 | 	 *             if the file can not be opened
358 | 	 */
359 | 	public InputStream get(String key) throws FileNotFoundException {
360 | 		File file = mCache.get(key);
361 | 		if (!file.exists())
362 | 			return null;
363 | 		return new FileInputStream(file);
364 | 	}
365 | 
366 | 	/**
367 | 	 * 保存 byte数据 到 缓存中
368 | 	 * 
369 | 	 * @param key
370 | 	 *            保存的key
371 | 	 * @param value
372 | 	 *            保存的数据
373 | 	 * @param saveTime
374 | 	 *            保存的时间,单位:秒
375 | 	 */
376 | 	public void put(String key, byte[] value, int saveTime) {
377 | 		put(key, Utils.newByteArrayWithDateInfo(saveTime, value));
378 | 	}
379 | 
380 | 	/**
381 | 	 * 获取 byte 数据
382 | 	 * 
383 | 	 * @param key
384 | 	 * @return byte 数据
385 | 	 */
386 | 	public byte[] getAsBinary(String key) {
387 | 		RandomAccessFile RAFile = null;
388 | 		boolean removeFile = false;
389 | 		try {
390 | 			File file = mCache.get(key);
391 | 			if (!file.exists())
392 | 				return null;
393 | 			RAFile = new RandomAccessFile(file, "r");
394 | 			byte[] byteArray = new byte[(int) RAFile.length()];
395 | 			RAFile.read(byteArray);
396 | 			if (!Utils.isDue(byteArray)) {
397 | 				return Utils.clearDateInfo(byteArray);
398 | 			} else {
399 | 				removeFile = true;
400 | 				return null;
401 | 			}
402 | 		} catch (Exception e) {
403 | 			e.printStackTrace();
404 | 			return null;
405 | 		} finally {
406 | 			if (RAFile != null) {
407 | 				try {
408 | 					RAFile.close();
409 | 				} catch (IOException e) {
410 | 					e.printStackTrace();
411 | 				}
412 | 			}
413 | 			if (removeFile)
414 | 				remove(key);
415 | 		}
416 | 	}
417 | 
418 | 	// =======================================
419 | 	// ============= 序列化 数据 读写 ===============
420 | 	// =======================================
421 | 	/**
422 | 	 * 保存 Serializable数据 到 缓存中
423 | 	 * 
424 | 	 * @param key
425 | 	 *            保存的key
426 | 	 * @param value
427 | 	 *            保存的value
428 | 	 */
429 | 	public void put(String key, Serializable value) {
430 | 		put(key, value, -1);
431 | 	}
432 | 
433 | 	/**
434 | 	 * 保存 Serializable数据到 缓存中
435 | 	 * 
436 | 	 * @param key
437 | 	 *            保存的key
438 | 	 * @param value
439 | 	 *            保存的value
440 | 	 * @param saveTime
441 | 	 *            保存的时间,单位:秒
442 | 	 */
443 | 	public void put(String key, Serializable value, int saveTime) {
444 | 		ByteArrayOutputStream baos = null;
445 | 		ObjectOutputStream oos = null;
446 | 		try {
447 | 			baos = new ByteArrayOutputStream();
448 | 			oos = new ObjectOutputStream(baos);
449 | 			oos.writeObject(value);
450 | 			byte[] data = baos.toByteArray();
451 | 			if (saveTime != -1) {
452 | 				put(key, data, saveTime);
453 | 			} else {
454 | 				put(key, data);
455 | 			}
456 | 		} catch (Exception e) {
457 | 			e.printStackTrace();
458 | 		} finally {
459 | 			try {
460 | 				oos.close();
461 | 			} catch (IOException e) {
462 | 			}
463 | 		}
464 | 	}
465 | 
466 | 	/**
467 | 	 * 读取 Serializable数据
468 | 	 * 
469 | 	 * @param key
470 | 	 * @return Serializable 数据
471 | 	 */
472 | 	public Object getAsObject(String key) {
473 | 		byte[] data = getAsBinary(key);
474 | 		if (data != null) {
475 | 			ByteArrayInputStream bais = null;
476 | 			ObjectInputStream ois = null;
477 | 			try {
478 | 				bais = new ByteArrayInputStream(data);
479 | 				ois = new ObjectInputStream(bais);
480 | 				Object reObject = ois.readObject();
481 | 				return reObject;
482 | 			} catch (Exception e) {
483 | 				e.printStackTrace();
484 | 				return null;
485 | 			} finally {
486 | 				try {
487 | 					if (bais != null)
488 | 						bais.close();
489 | 				} catch (IOException e) {
490 | 					e.printStackTrace();
491 | 				}
492 | 				try {
493 | 					if (ois != null)
494 | 						ois.close();
495 | 				} catch (IOException e) {
496 | 					e.printStackTrace();
497 | 				}
498 | 			}
499 | 		}
500 | 		return null;
501 | 
502 | 	}
503 | 
504 | 	// =======================================
505 | 	// ============== bitmap 数据 读写 =============
506 | 	// =======================================
507 | 	/**
508 | 	 * 保存 bitmap 到 缓存中
509 | 	 * 
510 | 	 * @param key
511 | 	 *            保存的key
512 | 	 * @param value
513 | 	 *            保存的bitmap数据
514 | 	 */
515 | 	public void put(String key, Bitmap value) {
516 | 		put(key, Utils.Bitmap2Bytes(value));
517 | 	}
518 | 
519 | 	/**
520 | 	 * 保存 bitmap 到 缓存中
521 | 	 * 
522 | 	 * @param key
523 | 	 *            保存的key
524 | 	 * @param value
525 | 	 *            保存的 bitmap 数据
526 | 	 * @param saveTime
527 | 	 *            保存的时间,单位:秒
528 | 	 */
529 | 	public void put(String key, Bitmap value, int saveTime) {
530 | 		put(key, Utils.Bitmap2Bytes(value), saveTime);
531 | 	}
532 | 
533 | 	/**
534 | 	 * 读取 bitmap 数据
535 | 	 * 
536 | 	 * @param key
537 | 	 * @return bitmap 数据
538 | 	 */
539 | 	public Bitmap getAsBitmap(String key) {
540 | 		if (getAsBinary(key) == null) {
541 | 			return null;
542 | 		}
543 | 		return Utils.Bytes2Bimap(getAsBinary(key));
544 | 	}
545 | 
546 | 	// =======================================
547 | 	// ============= drawable 数据 读写 =============
548 | 	// =======================================
549 | 	/**
550 | 	 * 保存 drawable 到 缓存中
551 | 	 * 
552 | 	 * @param key
553 | 	 *            保存的key
554 | 	 * @param value
555 | 	 *            保存的drawable数据
556 | 	 */
557 | 	public void put(String key, Drawable value) {
558 | 		put(key, Utils.drawable2Bitmap(value));
559 | 	}
560 | 
561 | 	/**
562 | 	 * 保存 drawable 到 缓存中
563 | 	 * 
564 | 	 * @param key
565 | 	 *            保存的key
566 | 	 * @param value
567 | 	 *            保存的 drawable 数据
568 | 	 * @param saveTime
569 | 	 *            保存的时间,单位:秒
570 | 	 */
571 | 	public void put(String key, Drawable value, int saveTime) {
572 | 		put(key, Utils.drawable2Bitmap(value), saveTime);
573 | 	}
574 | 
575 | 	/**
576 | 	 * 读取 Drawable 数据
577 | 	 * 
578 | 	 * @param key
579 | 	 * @return Drawable 数据
580 | 	 */
581 | 	public Drawable getAsDrawable(String key) {
582 | 		if (getAsBinary(key) == null) {
583 | 			return null;
584 | 		}
585 | 		return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key)));
586 | 	}
587 | 
588 | 	/**
589 | 	 * 获取缓存文件
590 | 	 * 
591 | 	 * @param key
592 | 	 * @return value 缓存的文件
593 | 	 */
594 | 	public File file(String key) {
595 | 		File f = mCache.newFile(key);
596 | 		if (f.exists())
597 | 			return f;
598 | 		return null;
599 | 	}
600 | 
601 | 	/**
602 | 	 * 移除某个key
603 | 	 * 
604 | 	 * @param key
605 | 	 * @return 是否移除成功
606 | 	 */
607 | 	public boolean remove(String key) {
608 | 		return mCache.remove(key);
609 | 	}
610 | 
611 | 	/**
612 | 	 * 清除所有数据
613 | 	 */
614 | 	public void clear() {
615 | 		mCache.clear();
616 | 	}
617 | 
618 | 	/**
619 | 	 * @title 缓存管理器
620 | 	 * @author 杨福海(michael) www.yangfuhai.com
621 | 	 * @version 1.0
622 | 	 */
623 | 	public class ACacheManager {
624 | 		private final AtomicLong cacheSize;
625 | 		private final AtomicInteger cacheCount;
626 | 		private final long sizeLimit;
627 | 		private final int countLimit;
628 | 		private final Map<File, Long> lastUsageDates = Collections.synchronizedMap(new HashMap<File, Long>());
629 | 		protected File cacheDir;
630 | 
631 | 		private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {
632 | 			this.cacheDir = cacheDir;
633 | 			this.sizeLimit = sizeLimit;
634 | 			this.countLimit = countLimit;
635 | 			cacheSize = new AtomicLong();
636 | 			cacheCount = new AtomicInteger();
637 | 			calculateCacheSizeAndCacheCount();
638 | 		}
639 | 
640 | 		/**
641 | 		 * 计算 cacheSize和cacheCount
642 | 		 */
643 | 		private void calculateCacheSizeAndCacheCount() {
644 | 			new Thread(new Runnable() {
645 | 				@Override
646 | 				public void run() {
647 | 					int size = 0;
648 | 					int count = 0;
649 | 					File[] cachedFiles = cacheDir.listFiles();
650 | 					if (cachedFiles != null) {
651 | 						for (File cachedFile : cachedFiles) {
652 | 							size += calculateSize(cachedFile);
653 | 							count += 1;
654 | 							lastUsageDates.put(cachedFile, cachedFile.lastModified());
655 | 						}
656 | 						cacheSize.set(size);
657 | 						cacheCount.set(count);
658 | 					}
659 | 				}
660 | 			}).start();
661 | 		}
662 | 
663 | 		private void put(File file) {
664 | 			int curCacheCount = cacheCount.get();
665 | 			while (curCacheCount + 1 > countLimit) {
666 | 				long freedSize = removeNext();
667 | 				cacheSize.addAndGet(-freedSize);
668 | 
669 | 				curCacheCount = cacheCount.addAndGet(-1);
670 | 			}
671 | 			cacheCount.addAndGet(1);
672 | 
673 | 			long valueSize = calculateSize(file);
674 | 			long curCacheSize = cacheSize.get();
675 | 			while (curCacheSize + valueSize > sizeLimit) {
676 | 				long freedSize = removeNext();
677 | 				curCacheSize = cacheSize.addAndGet(-freedSize);
678 | 			}
679 | 			cacheSize.addAndGet(valueSize);
680 | 
681 | 			Long currentTime = System.currentTimeMillis();
682 | 			file.setLastModified(currentTime);
683 | 			lastUsageDates.put(file, currentTime);
684 | 		}
685 | 
686 | 		private File get(String key) {
687 | 			File file = newFile(key);
688 | 			Long currentTime = System.currentTimeMillis();
689 | 			file.setLastModified(currentTime);
690 | 			lastUsageDates.put(file, currentTime);
691 | 
692 | 			return file;
693 | 		}
694 | 
695 | 		private File newFile(String key) {
696 | 			return new File(cacheDir, key.hashCode() + "");
697 | 		}
698 | 
699 | 		private boolean remove(String key) {
700 | 			File image = get(key);
701 | 			return image.delete();
702 | 		}
703 | 
704 | 		private void clear() {
705 | 			lastUsageDates.clear();
706 | 			cacheSize.set(0);
707 | 			File[] files = cacheDir.listFiles();
708 | 			if (files != null) {
709 | 				for (File f : files) {
710 | 					f.delete();
711 | 				}
712 | 			}
713 | 		}
714 | 
715 | 		/**
716 | 		 * 移除旧的文件
717 | 		 * 
718 | 		 * @return
719 | 		 */
720 | 		private long removeNext() {
721 | 			if (lastUsageDates.isEmpty()) {
722 | 				return 0;
723 | 			}
724 | 
725 | 			Long oldestUsage = null;
726 | 			File mostLongUsedFile = null;
727 | 			Set<Entry<File, Long>> entries = lastUsageDates.entrySet();
728 | 			synchronized (lastUsageDates) {
729 | 				for (Entry<File, Long> entry : entries) {
730 | 					if (mostLongUsedFile == null) {
731 | 						mostLongUsedFile = entry.getKey();
732 | 						oldestUsage = entry.getValue();
733 | 					} else {
734 | 						Long lastValueUsage = entry.getValue();
735 | 						if (lastValueUsage < oldestUsage) {
736 | 							oldestUsage = lastValueUsage;
737 | 							mostLongUsedFile = entry.getKey();
738 | 						}
739 | 					}
740 | 				}
741 | 			}
742 | 
743 | 			long fileSize = calculateSize(mostLongUsedFile);
744 | 			if (mostLongUsedFile.delete()) {
745 | 				lastUsageDates.remove(mostLongUsedFile);
746 | 			}
747 | 			return fileSize;
748 | 		}
749 | 
750 | 		private long calculateSize(File file) {
751 | 			return file.length();
752 | 		}
753 | 	}
754 | 
755 | 	/**
756 | 	 * @title 时间计算工具类
757 | 	 * @author 杨福海(michael) www.yangfuhai.com
758 | 	 * @version 1.0
759 | 	 */
760 | 	private static class Utils {
761 | 
762 | 		/**
763 | 		 * 判断缓存的String数据是否到期
764 | 		 * 
765 | 		 * @param str
766 | 		 * @return true:到期了 false:还没有到期
767 | 		 */
768 | 		private static boolean isDue(String str) {
769 | 			return isDue(str.getBytes());
770 | 		}
771 | 
772 | 		/**
773 | 		 * 判断缓存的byte数据是否到期
774 | 		 * 
775 | 		 * @param data
776 | 		 * @return true:到期了 false:还没有到期
777 | 		 */
778 | 		private static boolean isDue(byte[] data) {
779 | 			String[] strs = getDateInfoFromDate(data);
780 | 			if (strs != null && strs.length == 2) {
781 | 				String saveTimeStr = strs[0];
782 | 				while (saveTimeStr.startsWith("0")) {
783 | 					saveTimeStr = saveTimeStr.substring(1, saveTimeStr.length());
784 | 				}
785 | 				long saveTime = Long.valueOf(saveTimeStr);
786 | 				long deleteAfter = Long.valueOf(strs[1]);
787 | 				if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {
788 | 					return true;
789 | 				}
790 | 			}
791 | 			return false;
792 | 		}
793 | 
794 | 		private static String newStringWithDateInfo(int second, String strInfo) {
795 | 			return createDateInfo(second) + strInfo;
796 | 		}
797 | 
798 | 		private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) {
799 | 			byte[] data1 = createDateInfo(second).getBytes();
800 | 			byte[] retdata = new byte[data1.length + data2.length];
801 | 			System.arraycopy(data1, 0, retdata, 0, data1.length);
802 | 			System.arraycopy(data2, 0, retdata, data1.length, data2.length);
803 | 			return retdata;
804 | 		}
805 | 
806 | 		private static String clearDateInfo(String strInfo) {
807 | 			if (strInfo != null && hasDateInfo(strInfo.getBytes())) {
808 | 				strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1, strInfo.length());
809 | 			}
810 | 			return strInfo;
811 | 		}
812 | 
813 | 		private static byte[] clearDateInfo(byte[] data) {
814 | 			if (hasDateInfo(data)) {
815 | 				return copyOfRange(data, indexOf(data, mSeparator) + 1, data.length);
816 | 			}
817 | 			return data;
818 | 		}
819 | 
820 | 		private static boolean hasDateInfo(byte[] data) {
821 | 			return data != null && data.length > 15 && data[13] == '-' && indexOf(data, mSeparator) > 14;
822 | 		}
823 | 
824 | 		private static String[] getDateInfoFromDate(byte[] data) {
825 | 			if (hasDateInfo(data)) {
826 | 				String saveDate = new String(copyOfRange(data, 0, 13));
827 | 				String deleteAfter = new String(copyOfRange(data, 14, indexOf(data, mSeparator)));
828 | 				return new String[] { saveDate, deleteAfter };
829 | 			}
830 | 			return null;
831 | 		}
832 | 
833 | 		private static int indexOf(byte[] data, char c) {
834 | 			for (int i = 0; i < data.length; i++) {
835 | 				if (data[i] == c) {
836 | 					return i;
837 | 				}
838 | 			}
839 | 			return -1;
840 | 		}
841 | 
842 | 		private static byte[] copyOfRange(byte[] original, int from, int to) {
843 | 			int newLength = to - from;
844 | 			if (newLength < 0)
845 | 				throw new IllegalArgumentException(from + " > " + to);
846 | 			byte[] copy = new byte[newLength];
847 | 			System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
848 | 			return copy;
849 | 		}
850 | 
851 | 		private static final char mSeparator = ' ';
852 | 
853 | 		private static String createDateInfo(int second) {
854 | 			String currentTime = System.currentTimeMillis() + "";
855 | 			while (currentTime.length() < 13) {
856 | 				currentTime = "0" + currentTime;
857 | 			}
858 | 			return currentTime + "-" + second + mSeparator;
859 | 		}
860 | 
861 | 		/*
862 | 		 * Bitmap → byte[]
863 | 		 */
864 | 		private static byte[] Bitmap2Bytes(Bitmap bm) {
865 | 			if (bm == null) {
866 | 				return null;
867 | 			}
868 | 			ByteArrayOutputStream baos = new ByteArrayOutputStream();
869 | 			bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
870 | 			return baos.toByteArray();
871 | 		}
872 | 
873 | 		/*
874 | 		 * byte[] → Bitmap
875 | 		 */
876 | 		private static Bitmap Bytes2Bimap(byte[] b) {
877 | 			if (b.length == 0) {
878 | 				return null;
879 | 			}
880 | 			return BitmapFactory.decodeByteArray(b, 0, b.length);
881 | 		}
882 | 
883 | 		/*
884 | 		 * Drawable → Bitmap
885 | 		 */
886 | 		private static Bitmap drawable2Bitmap(Drawable drawable) {
887 | 			if (drawable == null) {
888 | 				return null;
889 | 			}
890 | 			// 取 drawable 的长宽
891 | 			int w = drawable.getIntrinsicWidth();
892 | 			int h = drawable.getIntrinsicHeight();
893 | 			// 取 drawable 的颜色格式
894 | 			Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
895 | 			// 建立对应 bitmap
896 | 			Bitmap bitmap = Bitmap.createBitmap(w, h, config);
897 | 			// 建立对应 bitmap 的画布
898 | 			Canvas canvas = new Canvas(bitmap);
899 | 			drawable.setBounds(0, 0, w, h);
900 | 			// 把 drawable 内容画到画布中
901 | 			drawable.draw(canvas);
902 | 			return bitmap;
903 | 		}
904 | 
905 | 		/*
906 | 		 * Bitmap → Drawable
907 | 		 */
908 | 		@SuppressWarnings("deprecation")
909 | 		private static Drawable bitmap2Drawable(Bitmap bm) {
910 | 			if (bm == null) {
911 | 				return null;
912 | 			}
913 | 			BitmapDrawable bd=new BitmapDrawable(bm);
914 | 			bd.setTargetDensity(bm.getDensity());
915 | 			return new BitmapDrawable(bm);
916 | 		}
917 | 	}
918 | 
919 | }
920 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/AndroidManifest.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     package="com.yangfuhai.asimplecachedemo"
 4 |     android:versionCode="1"
 5 |     android:versionName="1.0" >
 6 | 
 7 |     <uses-permission android:name="android.permission.INTERNET"></uses-permission>
 8 | 
 9 |     <uses-sdk
10 |         android:minSdkVersion="4"
11 |         android:targetSdkVersion="16" />
12 | 
13 |     <application
14 |         android:allowBackup="true"
15 |         android:icon="@drawable/ic_launcher"
16 |         android:label="@string/app_name"
17 |         android:theme="@style/AppTheme" >
18 |         <activity
19 |             android:name="com.yangfuhai.asimplecachedemo.MainActivity"
20 |             android:label="@string/app_name" >
21 |             <intent-filter>
22 |                 <action android:name="android.intent.action.MAIN" />
23 | 
24 |                 <category android:name="android.intent.category.LAUNCHER" />
25 |             </intent-filter>
26 |         </activity>
27 |         <activity android:name="com.yangfuhai.asimplecachedemo.AboutActivity" />
28 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveBitmapActivity" />
29 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveJsonObjectActivity" />
30 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveObjectActivity" />
31 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveStringActivity" />
32 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveMediaActivity" />
33 |         <activity
34 |             android:name="com.yangfuhai.asimplecachedemo.SaveDrawableActivity"
35 |             android:label="@string/title_activity_save_drawable" >
36 |         </activity>
37 |         <activity
38 |             android:name="com.yangfuhai.asimplecachedemo.SaveJsonArrayActivity"
39 |             android:label="@string/title_activity_save_json_array" >
40 |         </activity>
41 |     </application>
42 | 
43 | </manifest>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     package="com.yangfuhai.asimplecachedemo"
 4 |     android:versionCode="1"
 5 |     android:versionName="1.0" >
 6 | 
 7 |     <uses-permission android:name="android.permission.INTERNET"></uses-permission>
 8 | 
 9 |     <uses-sdk
10 |         android:minSdkVersion="4"
11 |         android:targetSdkVersion="16" />
12 | 
13 |     <application
14 |         android:allowBackup="true"
15 |         android:icon="@drawable/ic_launcher"
16 |         android:label="@string/app_name"
17 |         android:theme="@style/AppTheme" >
18 |         <activity
19 |             android:name="com.yangfuhai.asimplecachedemo.MainActivity"
20 |             android:label="@string/app_name" >
21 |             <intent-filter>
22 |                 <action android:name="android.intent.action.MAIN" />
23 | 
24 |                 <category android:name="android.intent.category.LAUNCHER" />
25 |             </intent-filter>
26 |         </activity>
27 |         <activity android:name="com.yangfuhai.asimplecachedemo.AboutActivity" />
28 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveBitmapActivity" />
29 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveJsonObjectActivity" />
30 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveObjectActivity" />
31 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveStringActivity" />
32 |         <activity android:name="com.yangfuhai.asimplecachedemo.SaveMediaActivity" />
33 |         <activity
34 |             android:name="com.yangfuhai.asimplecachedemo.SaveDrawableActivity"
35 |             android:label="@string/title_activity_save_drawable" >
36 |         </activity>
37 |         <activity
38 |             android:name="com.yangfuhai.asimplecachedemo.SaveJsonArrayActivity"
39 |             android:label="@string/title_activity_save_json_array" >
40 |         </activity>
41 |     </application>
42 | 
43 | </manifest>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/gen/com/yangfuhai/asimplecachedemo/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package com.yangfuhai.asimplecachedemo;
3 | 
4 | public final class BuildConfig {
5 |     public final static boolean DEBUG = true;
6 | }


--------------------------------------------------------------------------------
/AsimpleCacheDemo/gen/com/yangfuhai/asimplecachedemo/R.java:
--------------------------------------------------------------------------------
 1 | /* AUTO-GENERATED FILE.  DO NOT MODIFY.
 2 |  *
 3 |  * This class was automatically generated by the
 4 |  * aapt tool from the resource data it found.  It
 5 |  * should not be modified by hand.
 6 |  */
 7 | 
 8 | package com.yangfuhai.asimplecachedemo;
 9 | 
10 | public final class R {
11 |     public static final class attr {
12 |     }
13 |     public static final class drawable {
14 |         public static final int ic_launcher=0x7f020000;
15 |         public static final int img_test=0x7f020001;
16 |     }
17 |     public static final class id {
18 |         public static final int btn_about=0x7f070008;
19 |         public static final int btn_save_bitmap=0x7f070004;
20 |         public static final int btn_save_drawable=0x7f070006;
21 |         public static final int btn_save_file=0x7f070005;
22 |         public static final int btn_save_jsonarray=0x7f070003;
23 |         public static final int btn_save_jsonobject=0x7f070002;
24 |         public static final int btn_save_object=0x7f070007;
25 |         public static final int btn_save_string=0x7f070001;
26 |         public static final int et_string_input=0x7f070012;
27 |         public static final int iv_bitmap_res=0x7f070009;
28 |         public static final int iv_drawable_res=0x7f07000a;
29 |         public static final int menu_settings=0x7f070014;
30 |         public static final int text=0x7f07000b;
31 |         public static final int textView1=0x7f070000;
32 |         public static final int tv_jsonarray_original=0x7f07000c;
33 |         public static final int tv_jsonarray_res=0x7f07000d;
34 |         public static final int tv_jsonobject_original=0x7f07000e;
35 |         public static final int tv_jsonobject_res=0x7f07000f;
36 |         public static final int tv_object_original=0x7f070010;
37 |         public static final int tv_object_res=0x7f070011;
38 |         public static final int tv_string_res=0x7f070013;
39 |     }
40 |     public static final class layout {
41 |         public static final int activity_about=0x7f030000;
42 |         public static final int activity_main=0x7f030001;
43 |         public static final int activity_save_bitmap=0x7f030002;
44 |         public static final int activity_save_drawable=0x7f030003;
45 |         public static final int activity_save_file=0x7f030004;
46 |         public static final int activity_save_jsonarray=0x7f030005;
47 |         public static final int activity_save_jsonobject=0x7f030006;
48 |         public static final int activity_save_object=0x7f030007;
49 |         public static final int activity_save_string=0x7f030008;
50 |     }
51 |     public static final class menu {
52 |         public static final int activity_save_jsonarray=0x7f060000;
53 |     }
54 |     public static final class string {
55 |         public static final int app_name=0x7f040000;
56 |         public static final int hello_world=0x7f040001;
57 |         public static final int menu_settings=0x7f040002;
58 |         public static final int title_activity_save_drawable=0x7f040003;
59 |         public static final int title_activity_save_json_array=0x7f040004;
60 |     }
61 |     public static final class style {
62 |         /** 
63 |         Base application theme, dependent on API level. This theme is replaced
64 |         by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
65 |     
66 | 
67 |             Theme customizations available in newer API levels can go in
68 |             res/values-vXX/styles.xml, while customizations related to
69 |             backward-compatibility can go here.
70 |         
71 |          */
72 |         public static final int AppBaseTheme=0x7f050000;
73 |         /**  Application theme. 
74 |  All customizations that are NOT specific to a particular API-level can go here. 
75 |          */
76 |         public static final int AppTheme=0x7f050001;
77 |     }
78 | }
79 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangfuhai/ASimpleCache/7935b04751aa57299cfb8b89e5b1e12a2d96e7cb/AsimpleCacheDemo/ic_launcher-web.png


--------------------------------------------------------------------------------
/AsimpleCacheDemo/proguard-project.txt:
--------------------------------------------------------------------------------
 1 | # To enable ProGuard in your project, edit project.properties
 2 | # to define the proguard.config property as described in that file.
 3 | #
 4 | # Add project specific ProGuard rules here.
 5 | # By default, the flags in this file are appended to flags specified
 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
 7 | # You can edit the include path and order by changing the ProGuard
 8 | # include property in project.properties.
 9 | #
10 | # For more details, see
11 | #   http://developer.android.com/guide/developing/tools/proguard.html
12 | 
13 | # Add any project specific keep options here:
14 | 
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | #   public *;
20 | #}
21 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/project.properties:
--------------------------------------------------------------------------------
 1 | # This file is automatically generated by Android Tools.
 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
 3 | #
 4 | # This file must be checked in Version Control Systems.
 5 | #
 6 | # To customize properties used by the Ant build system edit
 7 | # "ant.properties", and override values to adapt the script to your
 8 | # project structure.
 9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 | 
13 | # Project target.
14 | target=android-19
15 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/drawable/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangfuhai/ASimpleCache/7935b04751aa57299cfb8b89e5b1e12a2d96e7cb/AsimpleCacheDemo/res/drawable/ic_launcher.png


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/drawable/img_test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangfuhai/ASimpleCache/7935b04751aa57299cfb8b89e5b1e12a2d96e7cb/AsimpleCacheDemo/res/drawable/img_test.png


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:orientation="vertical"
 6 |     tools:context=".MainActivity" >
 7 | 
 8 |     <TextView
 9 |         android:id="@+id/textView1"
10 |         android:layout_width="match_parent"
11 |         android:layout_height="wrap_content"
12 |         android:layout_centerHorizontal="true"
13 |         android:layout_centerVertical="true"
14 |         android:text="source:\n
15 |         http://github.com/yangfuhai/ASimpleCache \n
16 | author:\n
17 |         michael Yang       " />
18 | 
19 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:orientation="vertical"
 6 |     tools:context=".MainActivity" >
 7 | 
 8 |     <TextView
 9 |         android:id="@+id/textView1"
10 |         android:layout_width="match_parent"
11 |         android:layout_height="wrap_content"
12 |         android:text="@string/hello_world" />
13 | 
14 |     <Button
15 |         android:id="@+id/btn_save_string"
16 |         android:layout_width="match_parent"
17 |         android:layout_height="wrap_content"
18 |         android:onClick="string"
19 |         android:text="String Cache" />
20 | 
21 |     <Button
22 |         android:id="@+id/btn_save_jsonobject"
23 |         android:layout_width="match_parent"
24 |         android:layout_height="wrap_content"
25 |         android:onClick="jsonobject"
26 |         android:text="JsonObject Cache" />
27 | 
28 |     <Button
29 |         android:id="@+id/btn_save_jsonarray"
30 |         android:layout_width="match_parent"
31 |         android:layout_height="wrap_content"
32 |         android:onClick="jsonarray"
33 |         android:text="JsonArray Cache" />
34 | 
35 |     <Button
36 |         android:id="@+id/btn_save_bitmap"
37 |         android:layout_width="match_parent"
38 |         android:layout_height="wrap_content"
39 |         android:onClick="bitmap"
40 |         android:text="Bitmap Cache" />
41 | 
42 |     <Button
43 |         android:id="@+id/btn_save_file"
44 |         android:layout_width="match_parent"
45 |         android:layout_height="wrap_content"
46 |         android:onClick="media"
47 |         android:text="Media Cache" />
48 | 
49 |     <Button
50 |         android:id="@+id/btn_save_drawable"
51 |         android:layout_width="match_parent"
52 |         android:layout_height="wrap_content"
53 |         android:onClick="drawable"
54 |         android:text="Drawable Cache" />
55 | 
56 |     <Button
57 |         android:id="@+id/btn_save_object"
58 |         android:layout_width="match_parent"
59 |         android:layout_height="wrap_content"
60 |         android:onClick="object"
61 |         android:text="Object Cache" />
62 | 
63 |     <Button
64 |         android:id="@+id/btn_about"
65 |         android:layout_width="match_parent"
66 |         android:layout_height="wrap_content"
67 |         android:onClick="about"
68 |         android:text="btn_about" />
69 | 
70 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_bitmap.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:gravity="center|top"
 6 |     android:orientation="vertical"
 7 |     tools:context=".MainActivity" >
 8 | 
 9 |     <Button
10 |         android:layout_width="match_parent"
11 |         android:layout_height="wrap_content"
12 |         android:onClick="save"
13 |         android:text="save" />
14 | 
15 |     <Button
16 |         android:layout_width="match_parent"
17 |         android:layout_height="wrap_content"
18 |         android:onClick="read"
19 |         android:text="read" />
20 | 
21 |     <Button
22 |         android:layout_width="match_parent"
23 |         android:layout_height="wrap_content"
24 |         android:onClick="clear"
25 |         android:text="clear this Bitmap" />
26 | 
27 |     <ImageView
28 |         android:layout_width="wrap_content"
29 |         android:layout_height="wrap_content"
30 |         android:layout_margin="5dp"
31 |         android:contentDescription="@null"
32 |         android:src="@drawable/img_test" />
33 | 
34 |     <TextView
35 |         android:layout_width="match_parent"
36 |         android:layout_height="1dp"
37 |         android:background="#E5E5E5" />
38 | 
39 |     <ImageView
40 |         android:id="@+id/iv_bitmap_res"
41 |         android:layout_width="wrap_content"
42 |         android:layout_height="wrap_content"
43 |         android:layout_margin="5dp"
44 |         android:contentDescription="@null" />
45 | 
46 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_drawable.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:gravity="center|top"
 6 |     android:orientation="vertical"
 7 |     tools:context=".MainActivity" >
 8 | 
 9 |     <Button
10 |         android:layout_width="match_parent"
11 |         android:layout_height="wrap_content"
12 |         android:onClick="save"
13 |         android:text="save" />
14 | 
15 |     <Button
16 |         android:layout_width="match_parent"
17 |         android:layout_height="wrap_content"
18 |         android:onClick="read"
19 |         android:text="read" />
20 | 
21 |     <Button
22 |         android:layout_width="match_parent"
23 |         android:layout_height="wrap_content"
24 |         android:onClick="clear"
25 |         android:text="clear this Drawable" />
26 | 
27 |     <ImageView
28 |         android:layout_width="wrap_content"
29 |         android:layout_height="wrap_content"
30 |         android:layout_margin="5dp"
31 |         android:contentDescription="@null"
32 |         android:src="@drawable/img_test" />
33 | 
34 |     <TextView
35 |         android:layout_width="match_parent"
36 |         android:layout_height="1dp"
37 |         android:background="#E5E5E5" />
38 | 
39 |     <ImageView
40 |         android:id="@+id/iv_drawable_res"
41 |         android:layout_width="wrap_content"
42 |         android:layout_height="wrap_content"
43 |         android:layout_margin="5dp"
44 |         android:contentDescription="@null" />
45 | 
46 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_file.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:gravity="center|top"
 6 |     android:orientation="vertical"
 7 |     tools:context=".MainActivity" >
 8 | 
 9 |     <Button
10 |         android:layout_width="match_parent"
11 |         android:layout_height="wrap_content"
12 |         android:onClick="save"
13 |         android:text="save" />
14 | 
15 |     <Button
16 |         android:layout_width="match_parent"
17 |         android:layout_height="wrap_content"
18 |         android:onClick="read"
19 |         android:text="read" />
20 | 
21 |     <Button
22 |         android:layout_width="match_parent"
23 |         android:layout_height="wrap_content"
24 |         android:onClick="clear"
25 |         android:text="clear this Bitmap" />
26 | 
27 |     <TextView
28 |         android:layout_width="match_parent"
29 |         android:layout_height="wrap_content"
30 |         android:background="#E5E5E5"
31 |         android:id="@+id/text"/>
32 | 
33 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_jsonarray.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:gravity="center|top"
 6 |     android:orientation="vertical" >
 7 | 
 8 |     <Button
 9 |         android:layout_width="match_parent"
10 |         android:layout_height="wrap_content"
11 |         android:onClick="save"
12 |         android:text="save" />
13 | 
14 |     <Button
15 |         android:layout_width="match_parent"
16 |         android:layout_height="wrap_content"
17 |         android:onClick="read"
18 |         android:text="read" />
19 | 
20 |     <Button
21 |         android:layout_width="match_parent"
22 |         android:layout_height="wrap_content"
23 |         android:onClick="clear"
24 |         android:text="clear this JsonArray" />
25 | 
26 |     <TextView
27 |         android:id="@+id/tv_jsonarray_original"
28 |         android:layout_width="wrap_content"
29 |         android:layout_height="wrap_content"
30 |         android:layout_margin="5dp" />
31 | 
32 |     <TextView
33 |         android:layout_width="match_parent"
34 |         android:layout_height="1dp"
35 |         android:background="#E5E5E5" />
36 | 
37 |     <TextView
38 |         android:id="@+id/tv_jsonarray_res"
39 |         android:layout_width="wrap_content"
40 |         android:layout_height="wrap_content"
41 |         android:layout_margin="5dp" />
42 | 
43 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_jsonobject.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:gravity="center|top"
 6 |     android:orientation="vertical" >
 7 | 
 8 |     <Button
 9 |         android:layout_width="match_parent"
10 |         android:layout_height="wrap_content"
11 |         android:onClick="save"
12 |         android:text="save" />
13 | 
14 |     <Button
15 |         android:layout_width="match_parent"
16 |         android:layout_height="wrap_content"
17 |         android:onClick="read"
18 |         android:text="read" />
19 | 
20 |     <Button
21 |         android:layout_width="match_parent"
22 |         android:layout_height="wrap_content"
23 |         android:onClick="clear"
24 |         android:text="clear this JsonObject" />
25 | 
26 |     <TextView
27 |         android:id="@+id/tv_jsonobject_original"
28 |         android:layout_width="wrap_content"
29 |         android:layout_height="wrap_content"
30 |         android:layout_margin="5dp" />
31 | 
32 |     <TextView
33 |         android:layout_width="match_parent"
34 |         android:layout_height="1dp"
35 |         android:background="#E5E5E5" />
36 | 
37 |     <TextView
38 |         android:id="@+id/tv_jsonobject_res"
39 |         android:layout_width="wrap_content"
40 |         android:layout_height="wrap_content"
41 |         android:layout_margin="5dp" />
42 | 
43 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_object.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:gravity="center|top"
 6 |     android:orientation="vertical" >
 7 | 
 8 |     <Button
 9 |         android:layout_width="match_parent"
10 |         android:layout_height="wrap_content"
11 |         android:onClick="save"
12 |         android:text="save" />
13 | 
14 |     <Button
15 |         android:layout_width="match_parent"
16 |         android:layout_height="wrap_content"
17 |         android:onClick="read"
18 |         android:text="read" />
19 | 
20 |     <Button
21 |         android:layout_width="match_parent"
22 |         android:layout_height="wrap_content"
23 |         android:onClick="clear"
24 |         android:text="clear this Object" />
25 | 
26 |     <TextView
27 |         android:id="@+id/tv_object_original"
28 |         android:layout_width="wrap_content"
29 |         android:layout_height="wrap_content"
30 |         android:layout_margin="5dp" />
31 | 
32 |     <TextView
33 |         android:layout_width="match_parent"
34 |         android:layout_height="1dp"
35 |         android:background="#E5E5E5" />
36 | 
37 |     <TextView
38 |         android:id="@+id/tv_object_res"
39 |         android:layout_width="wrap_content"
40 |         android:layout_height="wrap_content"
41 |         android:layout_margin="5dp" />
42 | 
43 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_string.xml:
--------------------------------------------------------------------------------
 1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2 |     xmlns:tools="http://schemas.android.com/tools"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:orientation="vertical"
 6 |     tools:context=".MainActivity" >
 7 | 
 8 |     <EditText
 9 |         android:id="@+id/et_string_input"
10 |         android:layout_width="match_parent"
11 |         android:layout_height="wrap_content"
12 |         android:ems="10"
13 |         android:hint="input something ..." >
14 | 
15 |         <requestFocus />
16 |     </EditText>
17 | 
18 |     <Button
19 |         android:layout_width="match_parent"
20 |         android:layout_height="wrap_content"
21 |         android:onClick="save"
22 |         android:text="save" />
23 | 
24 |     <Button
25 |         android:layout_width="match_parent"
26 |         android:layout_height="wrap_content"
27 |         android:onClick="read"
28 |         android:text="read" />
29 | 
30 |     <Button
31 |         android:layout_width="match_parent"
32 |         android:layout_height="wrap_content"
33 |         android:onClick="clear"
34 |         android:text="clear this String" />
35 | 
36 |     <TextView
37 |         android:id="@+id/tv_string_res"
38 |         android:layout_width="match_parent"
39 |         android:layout_height="wrap_content" />
40 | 
41 | </LinearLayout>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/menu/activity_save_jsonarray.xml:
--------------------------------------------------------------------------------
1 | <menu xmlns:android="http://schemas.android.com/apk/res/android" >
2 | 
3 |     <item
4 |         android:id="@+id/menu_settings"
5 |         android:orderInCategory="100"
6 |         android:showAsAction="never"
7 |         android:title="@string/menu_settings"/>
8 | 
9 | </menu>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/values/strings.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <resources>
 3 | 
 4 |     <string name="app_name">AsimpleCacheDemo</string>
 5 |     <string name="hello_world">AsimpleCacheDemo </string>
 6 |     <string name="menu_settings">Settings</string>
 7 |     <string name="title_activity_save_drawable">SaveDrawableActivity</string>
 8 |     <string name="title_activity_save_json_array">SaveJsonArrayActivity</string>
 9 | 
10 | </resources>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/values/styles.xml:
--------------------------------------------------------------------------------
 1 | <resources>
 2 | 
 3 |     <!--
 4 |         Base application theme, dependent on API level. This theme is replaced
 5 |         by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 6 |     -->
 7 |     <style name="AppBaseTheme" parent="android:Theme.Light">
 8 |         <!--
 9 |             Theme customizations available in newer API levels can go in
10 |             res/values-vXX/styles.xml, while customizations related to
11 |             backward-compatibility can go here.
12 |         -->
13 |     </style>
14 | 
15 |     <!-- Application theme. -->
16 |     <style name="AppTheme" parent="AppBaseTheme">
17 |         <!-- All customizations that are NOT specific to a particular API-level can go here. -->
18 |     </style>
19 | 
20 | </resources>


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/AboutActivity.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo;
 2 | 
 3 | import android.app.Activity;
 4 | import android.os.Bundle;
 5 | 
 6 | public class AboutActivity extends Activity {
 7 | 
 8 | 	@Override
 9 | 	protected void onCreate(Bundle savedInstanceState) {
10 | 		super.onCreate(savedInstanceState);
11 | 		setContentView(R.layout.activity_about);
12 | 
13 | 	}
14 | 
15 | }
16 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/MainActivity.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo;
 2 | 
 3 | import android.app.Activity;
 4 | import android.content.Intent;
 5 | import android.os.Bundle;
 6 | import android.view.View;
 7 | 
 8 | /**
 9 |  * 
10 |  * @ClassName: MainActivity
11 |  * @Description: 主界面
12 |  * @Author Yoson Hao
13 |  * @WebSite www.haoyuexing.cn
14 |  * @Email haoyuexing@gmail.com
15 |  * @Date 2013-8-8 下午2:08:47
16 |  * 
17 |  */
18 | public class MainActivity extends Activity {
19 | 
20 | 	@Override
21 | 	protected void onCreate(Bundle savedInstanceState) {
22 | 		super.onCreate(savedInstanceState);
23 | 		setContentView(R.layout.activity_main);
24 | 	}
25 | 
26 | 	public void string(View v) {
27 | 		startActivity(new Intent().setClass(this, SaveStringActivity.class));
28 | 	}
29 | 
30 | 	public void jsonobject(View v) {
31 | 		startActivity(new Intent().setClass(this, SaveJsonObjectActivity.class));
32 | 	}
33 | 
34 | 	public void jsonarray(View v) {
35 | 		startActivity(new Intent().setClass(this, SaveJsonArrayActivity.class));
36 | 	}
37 | 
38 | 	public void bitmap(View v) {
39 | 		startActivity(new Intent().setClass(this, SaveBitmapActivity.class));
40 | 	}
41 | 
42 |     public void media(View v) {
43 |         startActivity(new Intent().setClass(this, SaveMediaActivity.class));
44 |     }
45 | 
46 | 	public void drawable(View v) {
47 | 		startActivity(new Intent().setClass(this, SaveDrawableActivity.class));
48 | 	}
49 | 
50 | 	public void object(View v) {
51 | 		startActivity(new Intent().setClass(this, SaveObjectActivity.class));
52 | 	}
53 | 
54 | 	public void about(View v) {
55 | 		startActivity(new Intent().setClass(this, AboutActivity.class));
56 | 	}
57 | 
58 | }
59 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/SaveBitmapActivity.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo;
 2 | 
 3 | import org.afinal.simplecache.ACache;
 4 | 
 5 | import android.app.Activity;
 6 | import android.content.res.Resources;
 7 | import android.graphics.Bitmap;
 8 | import android.graphics.BitmapFactory;
 9 | import android.os.Bundle;
10 | import android.view.View;
11 | import android.widget.ImageView;
12 | import android.widget.Toast;
13 | 
14 | /**
15 |  * 
16 |  * @ClassName: SaveBitmapActivity
17 |  * @Description: 缓存bitmap
18 |  * @Author Yoson Hao
19 |  * @WebSite www.haoyuexing.cn
20 |  * @Email haoyuexing@gmail.com
21 |  * @Date 2013-8-7 下午5:20:37
22 |  * 
23 |  */
24 | public class SaveBitmapActivity extends Activity {
25 | 
26 | 	private ImageView mIv_bitmap_res;
27 | 
28 | 	private ACache mCache;
29 | 
30 | 	@Override
31 | 	protected void onCreate(Bundle savedInstanceState) {
32 | 		super.onCreate(savedInstanceState);
33 | 		setContentView(R.layout.activity_save_bitmap);
34 | 		// 初始化控件
35 | 		initView();
36 | 
37 | 		mCache = ACache.get(this);
38 | 	}
39 | 
40 | 	/**
41 | 	 * 初始化控件
42 | 	 */
43 | 	private void initView() {
44 | 		mIv_bitmap_res = (ImageView) findViewById(R.id.iv_bitmap_res);
45 | 	}
46 | 
47 | 	/**
48 | 	 * 点击save事件
49 | 	 * 
50 | 	 * @param v
51 | 	 */
52 | 	public void save(View v) {
53 | 		Resources res = getResources();
54 | 		Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.img_test);
55 | 		mCache.put("testBitmap", bitmap);
56 | 	}
57 | 
58 | 	/**
59 | 	 * 点击read事件
60 | 	 * 
61 | 	 * @param v
62 | 	 */
63 | 	public void read(View v) {
64 | 		Bitmap testBitmap = mCache.getAsBitmap("testBitmap");
65 | 		if (testBitmap == null) {
66 | 			Toast.makeText(this, "Bitmap cache is null ...", Toast.LENGTH_SHORT)
67 | 					.show();
68 | 			mIv_bitmap_res.setImageBitmap(null);
69 | 			return;
70 | 		}
71 | 		mIv_bitmap_res.setImageBitmap(testBitmap);
72 | 	}
73 | 
74 | 	/**
75 | 	 * 点击clear事件
76 | 	 * 
77 | 	 * @param v
78 | 	 */
79 | 	public void clear(View v) {
80 | 		mCache.remove("testBitmap");
81 | 	}
82 | }
83 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/SaveDrawableActivity.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo;
 2 | 
 3 | import org.afinal.simplecache.ACache;
 4 | 
 5 | import android.os.Bundle;
 6 | import android.view.View;
 7 | import android.widget.ImageView;
 8 | import android.widget.Toast;
 9 | import android.app.Activity;
10 | import android.content.res.Resources;
11 | import android.graphics.drawable.Drawable;
12 | 
13 | /**
14 |  * 
15 |  * @ClassName: SaveDrawableActivity
16 |  * @Description: 缓存drawable
17 |  * @Author Yoson Hao
18 |  * @WebSite www.haoyuexing.cn
19 |  * @Email haoyuexing@gmail.com
20 |  * @Date 2013-8-8 上午10:40:47
21 |  * 
22 |  */
23 | public class SaveDrawableActivity extends Activity {
24 | 
25 | 	private ImageView mIv_drawable_res;
26 | 
27 | 	private ACache mCache;
28 | 
29 | 	@Override
30 | 	protected void onCreate(Bundle savedInstanceState) {
31 | 		super.onCreate(savedInstanceState);
32 | 		setContentView(R.layout.activity_save_drawable);
33 | 		// 初始化控件
34 | 		initView();
35 | 
36 | 		mCache = ACache.get(this);
37 | 	}
38 | 
39 | 	/**
40 | 	 * 初始化控件
41 | 	 */
42 | 	private void initView() {
43 | 		mIv_drawable_res = (ImageView) findViewById(R.id.iv_drawable_res);
44 | 	}
45 | 
46 | 	/**
47 | 	 * 点击save事件
48 | 	 * 
49 | 	 * @param v
50 | 	 */
51 | 	public void save(View v) {
52 | 		Resources res = getResources();
53 | 		Drawable drawable = res.getDrawable(R.drawable.img_test);
54 | 		mCache.put("testDrawable", drawable);
55 | 	}
56 | 
57 | 	/**
58 | 	 * 点击read事件
59 | 	 * 
60 | 	 * @param v
61 | 	 */
62 | 	public void read(View v) {
63 | 		Drawable testDrawable = mCache.getAsDrawable("testDrawable");
64 | 		if (testDrawable == null) {
65 | 			Toast.makeText(this, "Drawable cache is null ...",
66 | 					Toast.LENGTH_SHORT).show();
67 | 			mIv_drawable_res.setImageDrawable(null);
68 | 			return;
69 | 		}
70 | 		mIv_drawable_res.setImageDrawable(testDrawable);
71 | 	}
72 | 
73 | 	/**
74 | 	 * 点击clear事件
75 | 	 * 
76 | 	 * @param v
77 | 	 */
78 | 	public void clear(View v) {
79 | 		mCache.remove("testDrawable");
80 | 	}
81 | }


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/SaveJsonArrayActivity.java:
--------------------------------------------------------------------------------
  1 | package com.yangfuhai.asimplecachedemo;
  2 | 
  3 | import org.afinal.simplecache.ACache;
  4 | import org.json.JSONArray;
  5 | import org.json.JSONException;
  6 | import org.json.JSONObject;
  7 | 
  8 | import android.os.Bundle;
  9 | import android.view.View;
 10 | import android.widget.TextView;
 11 | import android.widget.Toast;
 12 | import android.app.Activity;
 13 | 
 14 | /**
 15 |  * 
 16 |  * @ClassName: SaveJsonArrayActivity
 17 |  * @Description: 缓存jsonarray
 18 |  * @Author Yoson Hao
 19 |  * @WebSite www.haoyuexing.cn
 20 |  * @Email haoyuexing@gmail.com
 21 |  * @Date 2013-8-8 下午1:54:19
 22 |  * 
 23 |  */
 24 | public class SaveJsonArrayActivity extends Activity {
 25 | 
 26 | 	private TextView mTv_jsonarray_original, mTv_jsonarray_res;
 27 | 	private JSONArray jsonArray;
 28 | 
 29 | 	private ACache mCache;
 30 | 
 31 | 	@Override
 32 | 	protected void onCreate(Bundle savedInstanceState) {
 33 | 		super.onCreate(savedInstanceState);
 34 | 		setContentView(R.layout.activity_save_jsonarray);
 35 | 		// 初始化控件
 36 | 		initView();
 37 | 
 38 | 		mCache = ACache.get(this);
 39 | 		jsonArray = new JSONArray();
 40 | 		JSONObject yosonJsonObject = new JSONObject();
 41 | 
 42 | 		try {
 43 | 			yosonJsonObject.put("name", "Yoson");
 44 | 			yosonJsonObject.put("age", 18);
 45 | 		} catch (JSONException e) {
 46 | 			e.printStackTrace();
 47 | 		}
 48 | 
 49 | 		JSONObject michaelJsonObject = new JSONObject();
 50 | 		try {
 51 | 			michaelJsonObject.put("name", "Michael");
 52 | 			michaelJsonObject.put("age", 25);
 53 | 		} catch (JSONException e) {
 54 | 			e.printStackTrace();
 55 | 		}
 56 | 
 57 | 		jsonArray.put(yosonJsonObject);
 58 | 		jsonArray.put(michaelJsonObject);
 59 | 
 60 | 		mTv_jsonarray_original.setText(jsonArray.toString());
 61 | 	}
 62 | 
 63 | 	/**
 64 | 	 * 初始化控件
 65 | 	 */
 66 | 	private void initView() {
 67 | 		mTv_jsonarray_original = (TextView) findViewById(R.id.tv_jsonarray_original);
 68 | 		mTv_jsonarray_res = (TextView) findViewById(R.id.tv_jsonarray_res);
 69 | 	}
 70 | 
 71 | 	/**
 72 | 	 * 点击save事件
 73 | 	 * 
 74 | 	 * @param v
 75 | 	 */
 76 | 	public void save(View v) {
 77 | 		mCache.put("testJsonArray", jsonArray);
 78 | 	}
 79 | 
 80 | 	/**
 81 | 	 * 点击read事件
 82 | 	 * 
 83 | 	 * @param v
 84 | 	 */
 85 | 	public void read(View v) {
 86 | 		JSONArray testJsonArray = mCache.getAsJSONArray("testJsonArray");
 87 | 		if (testJsonArray == null) {
 88 | 			Toast.makeText(this, "JSONArray cache is null ...",
 89 | 					Toast.LENGTH_SHORT).show();
 90 | 			mTv_jsonarray_res.setText(null);
 91 | 			return;
 92 | 		}
 93 | 		mTv_jsonarray_res.setText(testJsonArray.toString());
 94 | 	}
 95 | 
 96 | 	/**
 97 | 	 * 点击clear事件
 98 | 	 * 
 99 | 	 * @param v
100 | 	 */
101 | 	public void clear(View v) {
102 | 		mCache.remove("testJsonArray");
103 | 	}
104 | }
105 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/SaveJsonObjectActivity.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo;
 2 | 
 3 | import org.afinal.simplecache.ACache;
 4 | import org.json.JSONException;
 5 | import org.json.JSONObject;
 6 | 
 7 | import android.app.Activity;
 8 | import android.os.Bundle;
 9 | import android.view.View;
10 | import android.widget.TextView;
11 | import android.widget.Toast;
12 | 
13 | /**
14 |  * 
15 |  * @ClassName: SaveJsonObjectActivity
16 |  * @Description: 缓存jsonobject
17 |  * @Author Yoson Hao
18 |  * @WebSite www.haoyuexing.cn
19 |  * @Email haoyuexing@gmail.com
20 |  * @Date 2013-8-8 上午11:42:30
21 |  * 
22 |  */
23 | public class SaveJsonObjectActivity extends Activity {
24 | 
25 | 	private TextView mTv_jsonobject_original, mTv_jsonobject_res;
26 | 	private JSONObject jsonObject;
27 | 
28 | 	private ACache mCache;
29 | 
30 | 	@Override
31 | 	protected void onCreate(Bundle savedInstanceState) {
32 | 		super.onCreate(savedInstanceState);
33 | 		setContentView(R.layout.activity_save_jsonobject);
34 | 		// 初始化控件
35 | 		initView();
36 | 
37 | 		mCache = ACache.get(this);
38 | 		jsonObject = new JSONObject();
39 | 		try {
40 | 			jsonObject.put("name", "Yoson");
41 | 			jsonObject.put("age", 18);
42 | 		} catch (JSONException e) {
43 | 			e.printStackTrace();
44 | 		}
45 | 		mTv_jsonobject_original.setText(jsonObject.toString());
46 | 	}
47 | 
48 | 	/**
49 | 	 * 初始化控件
50 | 	 */
51 | 	private void initView() {
52 | 		mTv_jsonobject_original = (TextView) findViewById(R.id.tv_jsonobject_original);
53 | 		mTv_jsonobject_res = (TextView) findViewById(R.id.tv_jsonobject_res);
54 | 	}
55 | 
56 | 	/**
57 | 	 * 点击save事件
58 | 	 * 
59 | 	 * @param v
60 | 	 */
61 | 	public void save(View v) {
62 | 		mCache.put("testJsonObject", jsonObject);
63 | 	}
64 | 
65 | 	/**
66 | 	 * 点击read事件
67 | 	 * 
68 | 	 * @param v
69 | 	 */
70 | 	public void read(View v) {
71 | 		JSONObject testJsonObject = mCache.getAsJSONObject("testJsonObject");
72 | 		if (testJsonObject == null) {
73 | 			Toast.makeText(this, "JSONObject cache is null ...",
74 | 					Toast.LENGTH_SHORT).show();
75 | 			mTv_jsonobject_res.setText(null);
76 | 			return;
77 | 		}
78 | 		mTv_jsonobject_res.setText(testJsonObject.toString());
79 | 	}
80 | 
81 | 	/**
82 | 	 * 点击clear事件
83 | 	 * 
84 | 	 * @param v
85 | 	 */
86 | 	public void clear(View v) {
87 | 		mCache.remove("testJsonObject");
88 | 	}
89 | }
90 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/SaveMediaActivity.java:
--------------------------------------------------------------------------------
  1 | package com.yangfuhai.asimplecachedemo;
  2 | 
  3 | import android.app.Activity;
  4 | import android.os.Bundle;
  5 | import android.view.View;
  6 | import android.widget.TextView;
  7 | import android.widget.Toast;
  8 | 
  9 | import org.afinal.simplecache.ACache;
 10 | 
 11 | import java.io.FileNotFoundException;
 12 | import java.io.IOException;
 13 | import java.io.InputStream;
 14 | import java.io.OutputStream;
 15 | import java.net.HttpURLConnection;
 16 | import java.net.URL;
 17 | 
 18 | /**
 19 |  * 
 20 |  * @ClassName: SaveMediaActivity
 21 |  * @Description: 缓存bitmap
 22 |  * @Author Yoson Hao
 23 |  * @WebSite www.haoyuexing.cn
 24 |  * @Email haoyuexing@gmail.com
 25 |  * @Date 2013-8-7 下午5:20:37
 26 |  * 
 27 |  */
 28 | public class SaveMediaActivity extends Activity implements Runnable {
 29 |     private String mUrl = "http://www.largesound.com/ashborytour/sound/brobob.mp3";
 30 |     private static String CACHE_KEY = "brobob";
 31 | 
 32 |     private TextView text;
 33 |     private ACache mCache;
 34 | 
 35 | 	@Override
 36 | 	protected void onCreate(Bundle savedInstanceState) {
 37 | 		super.onCreate(savedInstanceState);
 38 | 		setContentView(R.layout.activity_save_file);
 39 | 
 40 | 		initView();
 41 | 
 42 | 		mCache = ACache.get(this);
 43 | 	}
 44 | 
 45 | 	/**
 46 | 	 * 初始化控件
 47 | 	 */
 48 | 	private void initView() {
 49 |         text = (TextView) findViewById(R.id.text);
 50 | 	}
 51 | 
 52 | 	/**
 53 | 	 * 点击save事件
 54 | 	 * 
 55 | 	 * @param v
 56 | 	 */
 57 | 	public void save(View v) {
 58 |         text.setText("Loading...");
 59 |         new Thread(this).start();
 60 |     }
 61 | 
 62 | 	/**
 63 | 	 * 点击read事件
 64 | 	 * 
 65 | 	 * @param v
 66 | 	 */
 67 | 	public void read(View v) {
 68 |         InputStream stream = null;
 69 |         try {
 70 |             stream = mCache.get(CACHE_KEY);
 71 |         } catch (FileNotFoundException e) {
 72 |             e.printStackTrace();
 73 |         }
 74 |         if (stream == null) {
 75 | 			Toast.makeText(this, "Bitmap cache is null ...", Toast.LENGTH_SHORT)
 76 | 					.show();
 77 |             text.setText("file not found");
 78 | 			return;
 79 | 		}
 80 |         try {
 81 |             text.setText("file size: " + stream.available());
 82 |         } catch (IOException e) {
 83 |             text.setText("error " + e.getMessage());
 84 |         }
 85 |     }
 86 | 
 87 | 	/**
 88 | 	 * 点击clear事件
 89 | 	 * 
 90 | 	 * @param v
 91 | 	 */
 92 | 	public void clear(View v) {
 93 | 		mCache.remove(CACHE_KEY);
 94 | 	}
 95 | 
 96 |     @Override
 97 |     public void run() {
 98 |         OutputStream ostream = null;
 99 |         try {
100 |             ostream = mCache.put(CACHE_KEY);
101 |         } catch (FileNotFoundException e) {
102 |             e.printStackTrace();
103 |         }
104 |         if (ostream == null){
105 |             Toast.makeText(this, "Open stream error!", Toast.LENGTH_SHORT)
106 |                     .show();
107 |             return;
108 |         }
109 |         try {
110 |             URL u = new URL(mUrl);
111 |             HttpURLConnection conn = (HttpURLConnection) u.openConnection();
112 |             conn.connect();
113 |             InputStream stream = conn.getInputStream();
114 | 
115 |             byte[] buff = new byte[1024];
116 |             int counter;
117 | 
118 |             while ((counter = stream.read(buff)) > 0){
119 |                 ostream.write(buff, 0, counter);
120 |             }
121 |         } catch (IOException e) {
122 |             e.printStackTrace();
123 |         } finally {
124 |             try {
125 |                 // cache update
126 |                 ostream.close();
127 |             } catch (IOException e) {
128 |                 e.printStackTrace();
129 |             }
130 |             runOnUiThread(new Runnable() {
131 |                 @Override
132 |                 public void run() {
133 |                     text = (TextView) findViewById(R.id.text);
134 |                     text.setText("done...");
135 |                 }
136 |             });
137 |         }
138 |     }
139 | }
140 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/SaveObjectActivity.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo;
 2 | 
 3 | import org.afinal.simplecache.ACache;
 4 | 
 5 | import com.yangfuhai.asimplecachedemo.beans.UserBean;
 6 | 
 7 | import android.app.Activity;
 8 | import android.os.Bundle;
 9 | import android.view.View;
10 | import android.widget.TextView;
11 | import android.widget.Toast;
12 | 
13 | /**
14 |  * 
15 |  * @ClassName: SaveObjectActivity
16 |  * @Description: 缓存jsonobject
17 |  * @Author Yoson Hao
18 |  * @WebSite www.haoyuexing.cn
19 |  * @Email haoyuexing@gmail.com
20 |  * @Date 2013-8-8 下午2:13:16
21 |  * 
22 |  */
23 | public class SaveObjectActivity extends Activity {
24 | 
25 | 	private TextView mTv_object_original, mTv_object_res;
26 | 	private UserBean userBean;
27 | 
28 | 	private ACache mCache;
29 | 
30 | 	@Override
31 | 	protected void onCreate(Bundle savedInstanceState) {
32 | 		super.onCreate(savedInstanceState);
33 | 		setContentView(R.layout.activity_save_object);
34 | 		// 初始化控件
35 | 		initView();
36 | 
37 | 		mCache = ACache.get(this);
38 | 		userBean = new UserBean();
39 | 		userBean.setAge("18");
40 | 		userBean.setName("HaoYoucai");
41 | 		mTv_object_original.setText(userBean.toString());
42 | 	}
43 | 
44 | 	/**
45 | 	 * 初始化控件
46 | 	 */
47 | 	private void initView() {
48 | 		mTv_object_original = (TextView) findViewById(R.id.tv_object_original);
49 | 		mTv_object_res = (TextView) findViewById(R.id.tv_object_res);
50 | 	}
51 | 
52 | 	/**
53 | 	 * 点击save事件
54 | 	 * 
55 | 	 * @param v
56 | 	 */
57 | 	public void save(View v) {
58 | 		mCache.put("testObject", userBean);
59 | 	}
60 | 
61 | 	/**
62 | 	 * 点击read事件
63 | 	 * 
64 | 	 * @param v
65 | 	 */
66 | 	public void read(View v) {
67 | 		UserBean testObject = (UserBean) mCache.getAsObject("testObject");
68 | 		if (testObject == null) {
69 | 			Toast.makeText(this, "Object cache is null ...", Toast.LENGTH_SHORT)
70 | 					.show();
71 | 			mTv_object_res.setText(null);
72 | 			return;
73 | 		}
74 | 		mTv_object_res.setText(testObject.toString());
75 | 	}
76 | 
77 | 	/**
78 | 	 * 点击clear事件
79 | 	 * 
80 | 	 * @param v
81 | 	 */
82 | 	public void clear(View v) {
83 | 		mCache.remove("testObject");
84 | 	}
85 | }
86 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/SaveStringActivity.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo;
 2 | 
 3 | import org.afinal.simplecache.ACache;
 4 | 
 5 | import android.app.Activity;
 6 | import android.os.Bundle;
 7 | import android.view.View;
 8 | import android.widget.EditText;
 9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 | 
12 | /**
13 |  * 
14 |  * @ClassName: SaveStringActivity
15 |  * @Description: 缓存string
16 |  * @Author Yoson Hao
17 |  * @WebSite www.haoyuexing.cn
18 |  * @Email haoyuexing@gmail.com
19 |  * @Date 2013-8-7 下午9:59:43
20 |  * 
21 |  */
22 | public class SaveStringActivity extends Activity {
23 | 
24 | 	private EditText mEt_string_input;
25 | 	private TextView mTv_string_res;
26 | 
27 | 	private ACache mCache;
28 | 
29 | 	@Override
30 | 	protected void onCreate(Bundle savedInstanceState) {
31 | 		super.onCreate(savedInstanceState);
32 | 		setContentView(R.layout.activity_save_string);
33 | 		// 初始化控件
34 | 		initView();
35 | 
36 | 		mCache = ACache.get(this);
37 | 	}
38 | 
39 | 	/**
40 | 	 * 初始化控件
41 | 	 */
42 | 	private void initView() {
43 | 		mEt_string_input = (EditText) findViewById(R.id.et_string_input);
44 | 		mTv_string_res = (TextView) findViewById(R.id.tv_string_res);
45 | 	}
46 | 
47 | 	/**
48 | 	 * 点击save事件
49 | 	 * 
50 | 	 * @param v
51 | 	 */
52 | 	public void save(View v) {
53 | 		if (mEt_string_input.getText().toString().trim().length() == 0) {
54 | 			Toast.makeText(
55 | 					this,
56 | 					"Cuz u input is a nullcharacter ... So , when u press \"read\" , if do not show any result , plz don't be surprise",
57 | 					Toast.LENGTH_SHORT).show();
58 | 		}
59 | 		mCache.put("testString", mEt_string_input.getText().toString());
60 | 	}
61 | 
62 | 	/**
63 | 	 * 点击read事件
64 | 	 * 
65 | 	 * @param v
66 | 	 */
67 | 	public void read(View v) {
68 | 		String testString = mCache.getAsString("testString");
69 | 		if (testString == null) {
70 | 			Toast.makeText(this, "String cache is null ...", Toast.LENGTH_SHORT)
71 | 					.show();
72 | 			mTv_string_res.setText(null);
73 | 			return;
74 | 		}
75 | 		mTv_string_res.setText(testString);
76 | 	}
77 | 
78 | 	/**
79 | 	 * 点击clear事件
80 | 	 * 
81 | 	 * @param v
82 | 	 */
83 | 	public void clear(View v) {
84 | 		mCache.remove("testString");
85 | 	}
86 | 
87 | }
88 | 


--------------------------------------------------------------------------------
/AsimpleCacheDemo/src/com/yangfuhai/asimplecachedemo/beans/UserBean.java:
--------------------------------------------------------------------------------
 1 | package com.yangfuhai.asimplecachedemo.beans;
 2 | 
 3 | import java.io.Serializable;
 4 | 
 5 | public class UserBean implements Serializable {
 6 | 
 7 | 	/**
 8 | 	 * 
 9 | 	 */
10 | 	private static final long serialVersionUID = 1L;
11 | 
12 | 	private String name;
13 | 	private String age;
14 | 
15 | 	public String getName() {
16 | 		return name;
17 | 	}
18 | 
19 | 	public void setName(String name) {
20 | 		this.name = name;
21 | 	}
22 | 
23 | 	public String getAge() {
24 | 		return age;
25 | 	}
26 | 
27 | 	public void setAge(String age) {
28 | 		this.age = age;
29 | 	}
30 | 
31 | 	@Override
32 | 	public String toString() {
33 | 		return "UserBean [name=" + name + ", age=" + age + "]";
34 | 	}
35 | 
36 | }
37 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
  1 | Apache License
  2 | Version 2.0, January 2004
  3 | http://www.apache.org/licenses/
  4 | 
  5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
  6 | 
  7 | 1. Definitions.
  8 | 
  9 | "License" shall mean the terms and conditions for use, reproduction, and
 10 | distribution as defined by Sections 1 through 9 of this document.
 11 | 
 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
 13 | owner that is granting the License.
 14 | 
 15 | "Legal Entity" shall mean the union of the acting entity and all other entities
 16 | that control, are controlled by, or are under common control with that entity.
 17 | For the purposes of this definition, "control" means (i) the power, direct or
 18 | indirect, to cause the direction or management of such entity, whether by
 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
 20 | outstanding shares, or (iii) beneficial ownership of such entity.
 21 | 
 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
 23 | permissions granted by this License.
 24 | 
 25 | "Source" form shall mean the preferred form for making modifications, including
 26 | but not limited to software source code, documentation source, and configuration
 27 | files.
 28 | 
 29 | "Object" form shall mean any form resulting from mechanical transformation or
 30 | translation of a Source form, including but not limited to compiled object code,
 31 | generated documentation, and conversions to other media types.
 32 | 
 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
 34 | available under the License, as indicated by a copyright notice that is included
 35 | in or attached to the work (an example is provided in the Appendix below).
 36 | 
 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
 38 | is based on (or derived from) the Work and for which the editorial revisions,
 39 | annotations, elaborations, or other modifications represent, as a whole, an
 40 | original work of authorship. For the purposes of this License, Derivative Works
 41 | shall not include works that remain separable from, or merely link (or bind by
 42 | name) to the interfaces of, the Work and Derivative Works thereof.
 43 | 
 44 | "Contribution" shall mean any work of authorship, including the original version
 45 | of the Work and any modifications or additions to that Work or Derivative Works
 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
 47 | by the copyright owner or by an individual or Legal Entity authorized to submit
 48 | on behalf of the copyright owner. For the purposes of this definition,
 49 | "submitted" means any form of electronic, verbal, or written communication sent
 50 | to the Licensor or its representatives, including but not limited to
 51 | communication on electronic mailing lists, source code control systems, and
 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
 53 | the purpose of discussing and improving the Work, but excluding communication
 54 | that is conspicuously marked or otherwise designated in writing by the copyright
 55 | owner as "Not a Contribution."
 56 | 
 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
 58 | of whom a Contribution has been received by Licensor and subsequently
 59 | incorporated within the Work.
 60 | 
 61 | 2. Grant of Copyright License.
 62 | 
 63 | Subject to the terms and conditions of this License, each Contributor hereby
 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
 65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
 66 | publicly display, publicly perform, sublicense, and distribute the Work and such
 67 | Derivative Works in Source or Object form.
 68 | 
 69 | 3. Grant of Patent License.
 70 | 
 71 | Subject to the terms and conditions of this License, each Contributor hereby
 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
 73 | irrevocable (except as stated in this section) patent license to make, have
 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
 75 | such license applies only to those patent claims licensable by such Contributor
 76 | that are necessarily infringed by their Contribution(s) alone or by combination
 77 | of their Contribution(s) with the Work to which such Contribution(s) was
 78 | submitted. If You institute patent litigation against any entity (including a
 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
 80 | Contribution incorporated within the Work constitutes direct or contributory
 81 | patent infringement, then any patent licenses granted to You under this License
 82 | for that Work shall terminate as of the date such litigation is filed.
 83 | 
 84 | 4. Redistribution.
 85 | 
 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
 87 | in any medium, with or without modifications, and in Source or Object form,
 88 | provided that You meet the following conditions:
 89 | 
 90 | You must give any other recipients of the Work or Derivative Works a copy of
 91 | this License; and
 92 | You must cause any modified files to carry prominent notices stating that You
 93 | changed the files; and
 94 | You must retain, in the Source form of any Derivative Works that You distribute,
 95 | all copyright, patent, trademark, and attribution notices from the Source form
 96 | of the Work, excluding those notices that do not pertain to any part of the
 97 | Derivative Works; and
 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
 99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 | 
117 | 5. Submission of Contributions.
118 | 
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 | 
126 | 6. Trademarks.
127 | 
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 | 
133 | 7. Disclaimer of Warranty.
134 | 
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 | 
144 | 8. Limitation of Liability.
145 | 
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 | 
156 | 9. Accepting Warranty or Additional Liability.
157 | 
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 | 
167 | END OF TERMS AND CONDITIONS
168 | 
169 | APPENDIX: How to apply the Apache License to your work
170 | 
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 | 
179 |    Copyright [yyyy] [name of copyright owner]
180 | 
181 |    Licensed under the Apache License, Version 2.0 (the "License");
182 |    you may not use this file except in compliance with the License.
183 |    You may obtain a copy of the License at
184 | 
185 |      http://www.apache.org/licenses/LICENSE-2.0
186 | 
187 |    Unless required by applicable law or agreed to in writing, software
188 |    distributed under the License is distributed on an "AS IS" BASIS,
189 |    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 |    See the License for the specific language governing permissions and
191 |    limitations under the License.
192 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | ASimpleCache
 2 | ============
 3 | 
 4 | 
 5 | ----
 6 |  ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。
 7 | 
 8 | 
 9 | ---
10 | ## 1、它可以缓存什么东西?
11 | 普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据。
12 | 
13 | 
14 | ## 2、它有什么特色?
15 | * 特色主要是:
16 |  *  1:轻,轻到只有一个JAVA文件。
17 |  *  2:可配置,可以配置缓存路径,缓存大小,缓存数量等。
18 |  *  3:可以设置缓存超时时间,缓存超时自动失效,并被删除。
19 |  *  4:支持多进程。
20 | 
21 | ##3、它在android中可以用在哪些场景?
22 | * 1、替换SharePreference当做配置文件
23 | * 2、可以缓存网络请求数据,比如oschina的android客户端可以缓存http请求的新闻内容,缓存时间假设为1个小时,超时后自动失效,让客户端重新请求新的数据,减少客户端流量,同时减少服务器并发量。
24 | * 3、您来说...
25 | 
26 | 
27 | ##4、如何使用 ASimpleCache?
28 | 以下有个小的demo,希望您能喜欢:
29 | 
30 | ```java
31 | ACache mCache = ACache.get(this);
32 | mCache.put("test_key1", "test value");
33 | mCache.put("test_key2", "test value", 10);//保存10秒,如果超过10秒去获取这个key,将为null
34 | mCache.put("test_key3", "test value", 2 * ACache.TIME_DAY);//保存两天,如果超过两天去获取这个key,将为null
35 | ```
36 | 获取数据
37 | ```java
38 | ACache mCache = ACache.get(this);
39 | String value = mCache.getAsString("test_key1");
40 | ```
41 | 
42 | 更多示例请见Demo
43 | 
44 | #关于作者michael
45 | * 屌丝程序员一枚,喜欢开源。
46 | * 个人博客:[http://www.yangfuhai.com](http://www.yangfuhai.com)
47 | * 交流QQ群 : 192341294(已满) 246710918(未满)
48 | 
49 | 
50 | 


--------------------------------------------------------------------------------
/source/src/org/afinal/simplecache/ACache.java:
--------------------------------------------------------------------------------
  1 | /**
  2 |  * Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com).
  3 |  *
  4 |  * Licensed under the Apache License, Version 2.0 (the "License");
  5 |  * you may not use this file except in compliance with the License.
  6 |  * You may obtain a copy of the License at
  7 |  *
  8 |  *      http://www.apache.org/licenses/LICENSE-2.0
  9 |  *
 10 |  * Unless required by applicable law or agreed to in writing, software
 11 |  * distributed under the License is distributed on an "AS IS" BASIS,
 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 |  * See the License for the specific language governing permissions and
 14 |  * limitations under the License.
 15 |  */
 16 | package org.afinal.simplecache;
 17 | 
 18 | import java.io.BufferedReader;
 19 | import java.io.BufferedWriter;
 20 | import java.io.ByteArrayInputStream;
 21 | import java.io.ByteArrayOutputStream;
 22 | import java.io.File;
 23 | import java.io.FileOutputStream;
 24 | import java.io.FileReader;
 25 | import java.io.FileWriter;
 26 | import java.io.IOException;
 27 | import java.io.ObjectInputStream;
 28 | import java.io.ObjectOutputStream;
 29 | import java.io.RandomAccessFile;
 30 | import java.io.Serializable;
 31 | import java.util.Collections;
 32 | import java.util.HashMap;
 33 | import java.util.Map;
 34 | import java.util.Map.Entry;
 35 | import java.util.Set;
 36 | import java.util.concurrent.atomic.AtomicInteger;
 37 | import java.util.concurrent.atomic.AtomicLong;
 38 | 
 39 | import org.json.JSONArray;
 40 | import org.json.JSONObject;
 41 | 
 42 | import android.content.Context;
 43 | import android.graphics.Bitmap;
 44 | import android.graphics.BitmapFactory;
 45 | import android.graphics.Canvas;
 46 | import android.graphics.PixelFormat;
 47 | import android.graphics.drawable.BitmapDrawable;
 48 | import android.graphics.drawable.Drawable;
 49 | 
 50 | /**
 51 |  * @author Michael Yang(www.yangfuhai.com) update at 2013.08.07
 52 |  */
 53 | public class ACache {
 54 | 	public static final int TIME_HOUR = 60 * 60;
 55 | 	public static final int TIME_DAY = TIME_HOUR * 24;
 56 | 	private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb
 57 | 	private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量
 58 | 	private static Map<String, ACache> mInstanceMap = new HashMap<String, ACache>();
 59 | 	private ACacheManager mCache;
 60 | 
 61 | 	public static ACache get(Context ctx) {
 62 | 		return get(ctx, "ACache");
 63 | 	}
 64 | 
 65 | 	public static ACache get(Context ctx, String cacheName) {
 66 | 		File f = new File(ctx.getCacheDir(), cacheName);
 67 | 		return get(f, MAX_SIZE, MAX_COUNT);
 68 | 	}
 69 | 
 70 | 	public static ACache get(File cacheDir) {
 71 | 		return get(cacheDir, MAX_SIZE, MAX_COUNT);
 72 | 	}
 73 | 
 74 | 	public static ACache get(Context ctx, long max_zise, int max_count) {
 75 | 		File f = new File(ctx.getCacheDir(), "ACache");
 76 | 		return get(f, max_zise, max_count);
 77 | 	}
 78 | 
 79 | 	public static ACache get(File cacheDir, long max_zise, int max_count) {
 80 | 		ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());
 81 | 		if (manager == null) {
 82 | 			manager = new ACache(cacheDir, max_zise, max_count);
 83 | 			mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
 84 | 		}
 85 | 		return manager;
 86 | 	}
 87 | 
 88 | 	private static String myPid() {
 89 | 		return "_" + android.os.Process.myPid();
 90 | 	}
 91 | 
 92 | 	private ACache(File cacheDir, long max_size, int max_count) {
 93 | 		if (!cacheDir.exists() && !cacheDir.mkdirs()) {
 94 | 			throw new RuntimeException("can't make dirs in "
 95 | 					+ cacheDir.getAbsolutePath());
 96 | 		}
 97 | 		mCache = new ACacheManager(cacheDir, max_size, max_count);
 98 | 	}
 99 | 
100 | 	// =======================================
101 | 	// ============ String数据 读写 ==============
102 | 	// =======================================
103 | 	/**
104 | 	 * 保存 String数据 到 缓存中
105 | 	 * 
106 | 	 * @param key
107 | 	 *            保存的key
108 | 	 * @param value
109 | 	 *            保存的String数据
110 | 	 */
111 | 	public void put(String key, String value) {
112 | 		File file = mCache.newFile(key);
113 | 		BufferedWriter out = null;
114 | 		try {
115 | 			out = new BufferedWriter(new FileWriter(file), 1024);
116 | 			out.write(value);
117 | 		} catch (IOException e) {
118 | 			e.printStackTrace();
119 | 		} finally {
120 | 			if (out != null) {
121 | 				try {
122 | 					out.flush();
123 | 					out.close();
124 | 				} catch (IOException e) {
125 | 					e.printStackTrace();
126 | 				}
127 | 			}
128 | 			mCache.put(file);
129 | 		}
130 | 	}
131 | 
132 | 	/**
133 | 	 * 保存 String数据 到 缓存中
134 | 	 * 
135 | 	 * @param key
136 | 	 *            保存的key
137 | 	 * @param value
138 | 	 *            保存的String数据
139 | 	 * @param saveTime
140 | 	 *            保存的时间,单位:秒
141 | 	 */
142 | 	public void put(String key, String value, int saveTime) {
143 | 		put(key, Utils.newStringWithDateInfo(saveTime, value));
144 | 	}
145 | 
146 | 	/**
147 | 	 * 读取 String数据
148 | 	 * 
149 | 	 * @param key
150 | 	 * @return String 数据
151 | 	 */
152 | 	public String getAsString(String key) {
153 | 		File file = mCache.get(key);
154 | 		if (!file.exists())
155 | 			return null;
156 | 		boolean removeFile = false;
157 | 		BufferedReader in = null;
158 | 		try {
159 | 			in = new BufferedReader(new FileReader(file));
160 | 			String readString = "";
161 | 			String currentLine;
162 | 			while ((currentLine = in.readLine()) != null) {
163 | 				readString += currentLine;
164 | 			}
165 | 			if (!Utils.isDue(readString)) {
166 | 				return Utils.clearDateInfo(readString);
167 | 			} else {
168 | 				removeFile = true;
169 | 				return null;
170 | 			}
171 | 		} catch (IOException e) {
172 | 			e.printStackTrace();
173 | 			return null;
174 | 		} finally {
175 | 			if (in != null) {
176 | 				try {
177 | 					in.close();
178 | 				} catch (IOException e) {
179 | 					e.printStackTrace();
180 | 				}
181 | 			}
182 | 			if (removeFile)
183 | 				remove(key);
184 | 		}
185 | 	}
186 | 
187 | 	// =======================================
188 | 	// ============= JSONObject 数据 读写 ==============
189 | 	// =======================================
190 | 	/**
191 | 	 * 保存 JSONObject数据 到 缓存中
192 | 	 * 
193 | 	 * @param key
194 | 	 *            保存的key
195 | 	 * @param value
196 | 	 *            保存的JSON数据
197 | 	 */
198 | 	public void put(String key, JSONObject value) {
199 | 		put(key, value.toString());
200 | 	}
201 | 
202 | 	/**
203 | 	 * 保存 JSONObject数据 到 缓存中
204 | 	 * 
205 | 	 * @param key
206 | 	 *            保存的key
207 | 	 * @param value
208 | 	 *            保存的JSONObject数据
209 | 	 * @param saveTime
210 | 	 *            保存的时间,单位:秒
211 | 	 */
212 | 	public void put(String key, JSONObject value, int saveTime) {
213 | 		put(key, value.toString(), saveTime);
214 | 	}
215 | 
216 | 	/**
217 | 	 * 读取JSONObject数据
218 | 	 * 
219 | 	 * @param key
220 | 	 * @return JSONObject数据
221 | 	 */
222 | 	public JSONObject getAsJSONObject(String key) {
223 | 		String JSONString = getAsString(key);
224 | 		try {
225 | 			JSONObject obj = new JSONObject(JSONString);
226 | 			return obj;
227 | 		} catch (Exception e) {
228 | 			e.printStackTrace();
229 | 			return null;
230 | 		}
231 | 	}
232 | 
233 | 	// =======================================
234 | 	// ============ JSONArray 数据 读写 =============
235 | 	// =======================================
236 | 	/**
237 | 	 * 保存 JSONArray数据 到 缓存中
238 | 	 * 
239 | 	 * @param key
240 | 	 *            保存的key
241 | 	 * @param value
242 | 	 *            保存的JSONArray数据
243 | 	 */
244 | 	public void put(String key, JSONArray value) {
245 | 		put(key, value.toString());
246 | 	}
247 | 
248 | 	/**
249 | 	 * 保存 JSONArray数据 到 缓存中
250 | 	 * 
251 | 	 * @param key
252 | 	 *            保存的key
253 | 	 * @param value
254 | 	 *            保存的JSONArray数据
255 | 	 * @param saveTime
256 | 	 *            保存的时间,单位:秒
257 | 	 */
258 | 	public void put(String key, JSONArray value, int saveTime) {
259 | 		put(key, value.toString(), saveTime);
260 | 	}
261 | 
262 | 	/**
263 | 	 * 读取JSONArray数据
264 | 	 * 
265 | 	 * @param key
266 | 	 * @return JSONArray数据
267 | 	 */
268 | 	public JSONArray getAsJSONArray(String key) {
269 | 		String JSONString = getAsString(key);
270 | 		try {
271 | 			JSONArray obj = new JSONArray(JSONString);
272 | 			return obj;
273 | 		} catch (Exception e) {
274 | 			e.printStackTrace();
275 | 			return null;
276 | 		}
277 | 	}
278 | 
279 | 	// =======================================
280 | 	// ============== byte 数据 读写 =============
281 | 	// =======================================
282 | 	/**
283 | 	 * 保存 byte数据 到 缓存中
284 | 	 * 
285 | 	 * @param key
286 | 	 *            保存的key
287 | 	 * @param value
288 | 	 *            保存的数据
289 | 	 */
290 | 	public void put(String key, byte[] value) {
291 | 		File file = mCache.newFile(key);
292 | 		FileOutputStream out = null;
293 | 		try {
294 | 			out = new FileOutputStream(file);
295 | 			out.write(value);
296 | 		} catch (Exception e) {
297 | 			e.printStackTrace();
298 | 		} finally {
299 | 			if (out != null) {
300 | 				try {
301 | 					out.flush();
302 | 					out.close();
303 | 				} catch (IOException e) {
304 | 					e.printStackTrace();
305 | 				}
306 | 			}
307 | 			mCache.put(file);
308 | 		}
309 | 	}
310 | 
311 | 	/**
312 | 	 * 保存 byte数据 到 缓存中
313 | 	 * 
314 | 	 * @param key
315 | 	 *            保存的key
316 | 	 * @param value
317 | 	 *            保存的数据
318 | 	 * @param saveTime
319 | 	 *            保存的时间,单位:秒
320 | 	 */
321 | 	public void put(String key, byte[] value, int saveTime) {
322 | 		put(key, Utils.newByteArrayWithDateInfo(saveTime, value));
323 | 	}
324 | 
325 | 	/**
326 | 	 * 获取 byte 数据
327 | 	 * 
328 | 	 * @param key
329 | 	 * @return byte 数据
330 | 	 */
331 | 	public byte[] getAsBinary(String key) {
332 | 		RandomAccessFile RAFile = null;
333 | 		boolean removeFile = false;
334 | 		try {
335 | 			File file = mCache.get(key);
336 | 			if (!file.exists())
337 | 				return null;
338 | 			RAFile = new RandomAccessFile(file, "r");
339 | 			byte[] byteArray = new byte[(int) RAFile.length()];
340 | 			RAFile.read(byteArray);
341 | 			if (!Utils.isDue(byteArray)) {
342 | 				return Utils.clearDateInfo(byteArray);
343 | 			} else {
344 | 				removeFile = true;
345 | 				return null;
346 | 			}
347 | 		} catch (Exception e) {
348 | 			e.printStackTrace();
349 | 			return null;
350 | 		} finally {
351 | 			if (RAFile != null) {
352 | 				try {
353 | 					RAFile.close();
354 | 				} catch (IOException e) {
355 | 					e.printStackTrace();
356 | 				}
357 | 			}
358 | 			if (removeFile)
359 | 				remove(key);
360 | 		}
361 | 	}
362 | 
363 | 	// =======================================
364 | 	// ============= 序列化 数据 读写 ===============
365 | 	// =======================================
366 | 	/**
367 | 	 * 保存 Serializable数据 到 缓存中
368 | 	 * 
369 | 	 * @param key
370 | 	 *            保存的key
371 | 	 * @param value
372 | 	 *            保存的value
373 | 	 */
374 | 	public void put(String key, Serializable value) {
375 | 		put(key, value, -1);
376 | 	}
377 | 
378 | 	/**
379 | 	 * 保存 Serializable数据到 缓存中
380 | 	 * 
381 | 	 * @param key
382 | 	 *            保存的key
383 | 	 * @param value
384 | 	 *            保存的value
385 | 	 * @param saveTime
386 | 	 *            保存的时间,单位:秒
387 | 	 */
388 | 	public void put(String key, Serializable value, int saveTime) {
389 | 		ByteArrayOutputStream baos = null;
390 | 		ObjectOutputStream oos = null;
391 | 		try {
392 | 			baos = new ByteArrayOutputStream();
393 | 			oos = new ObjectOutputStream(baos);
394 | 			oos.writeObject(value);
395 | 			byte[] data = baos.toByteArray();
396 | 			if (saveTime != -1) {
397 | 				put(key, data, saveTime);
398 | 			} else {
399 | 				put(key, data);
400 | 			}
401 | 		} catch (Exception e) {
402 | 			e.printStackTrace();
403 | 		} finally {
404 | 			try {
405 | 				oos.close();
406 | 			} catch (IOException e) {
407 | 			}
408 | 		}
409 | 	}
410 | 
411 | 	/**
412 | 	 * 读取 Serializable数据
413 | 	 * 
414 | 	 * @param key
415 | 	 * @return Serializable 数据
416 | 	 */
417 | 	public Object getAsObject(String key) {
418 | 		byte[] data = getAsBinary(key);
419 | 		if (data != null) {
420 | 			ByteArrayInputStream bais = null;
421 | 			ObjectInputStream ois = null;
422 | 			try {
423 | 				bais = new ByteArrayInputStream(data);
424 | 				ois = new ObjectInputStream(bais);
425 | 				Object reObject = ois.readObject();
426 | 				return reObject;
427 | 			} catch (Exception e) {
428 | 				e.printStackTrace();
429 | 				return null;
430 | 			} finally {
431 | 				try {
432 | 					if (bais != null)
433 | 						bais.close();
434 | 				} catch (IOException e) {
435 | 					e.printStackTrace();
436 | 				}
437 | 				try {
438 | 					if (ois != null)
439 | 						ois.close();
440 | 				} catch (IOException e) {
441 | 					e.printStackTrace();
442 | 				}
443 | 			}
444 | 		}
445 | 		return null;
446 | 
447 | 	}
448 | 
449 | 	// =======================================
450 | 	// ============== bitmap 数据 读写 =============
451 | 	// =======================================
452 | 	/**
453 | 	 * 保存 bitmap 到 缓存中
454 | 	 * 
455 | 	 * @param key
456 | 	 *            保存的key
457 | 	 * @param value
458 | 	 *            保存的bitmap数据
459 | 	 */
460 | 	public void put(String key, Bitmap value) {
461 | 		put(key, Utils.Bitmap2Bytes(value));
462 | 	}
463 | 
464 | 	/**
465 | 	 * 保存 bitmap 到 缓存中
466 | 	 * 
467 | 	 * @param key
468 | 	 *            保存的key
469 | 	 * @param value
470 | 	 *            保存的 bitmap 数据
471 | 	 * @param saveTime
472 | 	 *            保存的时间,单位:秒
473 | 	 */
474 | 	public void put(String key, Bitmap value, int saveTime) {
475 | 		put(key, Utils.Bitmap2Bytes(value), saveTime);
476 | 	}
477 | 
478 | 	/**
479 | 	 * 读取 bitmap 数据
480 | 	 * 
481 | 	 * @param key
482 | 	 * @return bitmap 数据
483 | 	 */
484 | 	public Bitmap getAsBitmap(String key) {
485 | 		if (getAsBinary(key) == null) {
486 | 			return null;
487 | 		}
488 | 		return Utils.Bytes2Bimap(getAsBinary(key));
489 | 	}
490 | 
491 | 	// =======================================
492 | 	// ============= drawable 数据 读写 =============
493 | 	// =======================================
494 | 	/**
495 | 	 * 保存 drawable 到 缓存中
496 | 	 * 
497 | 	 * @param key
498 | 	 *            保存的key
499 | 	 * @param value
500 | 	 *            保存的drawable数据
501 | 	 */
502 | 	public void put(String key, Drawable value) {
503 | 		put(key, Utils.drawable2Bitmap(value));
504 | 	}
505 | 
506 | 	/**
507 | 	 * 保存 drawable 到 缓存中
508 | 	 * 
509 | 	 * @param key
510 | 	 *            保存的key
511 | 	 * @param value
512 | 	 *            保存的 drawable 数据
513 | 	 * @param saveTime
514 | 	 *            保存的时间,单位:秒
515 | 	 */
516 | 	public void put(String key, Drawable value, int saveTime) {
517 | 		put(key, Utils.drawable2Bitmap(value), saveTime);
518 | 	}
519 | 
520 | 	/**
521 | 	 * 读取 Drawable 数据
522 | 	 * 
523 | 	 * @param key
524 | 	 * @return Drawable 数据
525 | 	 */
526 | 	public Drawable getAsDrawable(String key) {
527 | 		if (getAsBinary(key) == null) {
528 | 			return null;
529 | 		}
530 | 		return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key)));
531 | 	}
532 | 
533 | 	/**
534 | 	 * 获取缓存文件
535 | 	 * 
536 | 	 * @param key
537 | 	 * @return value 缓存的文件
538 | 	 */
539 | 	public File file(String key) {
540 | 		File f = mCache.newFile(key);
541 | 		if (f.exists())
542 | 			return f;
543 | 		return null;
544 | 	}
545 | 
546 | 	/**
547 | 	 * 移除某个key
548 | 	 * 
549 | 	 * @param key
550 | 	 * @return 是否移除成功
551 | 	 */
552 | 	public boolean remove(String key) {
553 | 		return mCache.remove(key);
554 | 	}
555 | 
556 | 	/**
557 | 	 * 清除所有数据
558 | 	 */
559 | 	public void clear() {
560 | 		mCache.clear();
561 | 	}
562 | 
563 | 	/**
564 | 	 * @title 缓存管理器
565 | 	 * @author 杨福海(michael) www.yangfuhai.com
566 | 	 * @version 1.0
567 | 	 */
568 | 	public class ACacheManager {
569 | 		private final AtomicLong cacheSize;
570 | 		private final AtomicInteger cacheCount;
571 | 		private final long sizeLimit;
572 | 		private final int countLimit;
573 | 		private final Map<File, Long> lastUsageDates = Collections
574 | 				.synchronizedMap(new HashMap<File, Long>());
575 | 		protected File cacheDir;
576 | 
577 | 		private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {
578 | 			this.cacheDir = cacheDir;
579 | 			this.sizeLimit = sizeLimit;
580 | 			this.countLimit = countLimit;
581 | 			cacheSize = new AtomicLong();
582 | 			cacheCount = new AtomicInteger();
583 | 			calculateCacheSizeAndCacheCount();
584 | 		}
585 | 
586 | 		/**
587 | 		 * 计算 cacheSize和cacheCount
588 | 		 */
589 | 		private void calculateCacheSizeAndCacheCount() {
590 | 			new Thread(new Runnable() {
591 | 				@Override
592 | 				public void run() {
593 | 					int size = 0;
594 | 					int count = 0;
595 | 					File[] cachedFiles = cacheDir.listFiles();
596 | 					if (cachedFiles != null) {
597 | 						for (File cachedFile : cachedFiles) {
598 | 							size += calculateSize(cachedFile);
599 | 							count += 1;
600 | 							lastUsageDates.put(cachedFile,
601 | 									cachedFile.lastModified());
602 | 						}
603 | 						cacheSize.set(size);
604 | 						cacheCount.set(count);
605 | 					}
606 | 				}
607 | 			}).start();
608 | 		}
609 | 
610 | 		private void put(File file) {
611 | 			int curCacheCount = cacheCount.get();
612 | 			while (curCacheCount + 1 > countLimit) {
613 | 				long freedSize = removeNext();
614 | 				cacheSize.addAndGet(-freedSize);
615 | 
616 | 				curCacheCount = cacheCount.addAndGet(-1);
617 | 			}
618 | 			cacheCount.addAndGet(1);
619 | 
620 | 			long valueSize = calculateSize(file);
621 | 			long curCacheSize = cacheSize.get();
622 | 			while (curCacheSize + valueSize > sizeLimit) {
623 | 				long freedSize = removeNext();
624 | 				curCacheSize = cacheSize.addAndGet(-freedSize);
625 | 			}
626 | 			cacheSize.addAndGet(valueSize);
627 | 
628 | 			Long currentTime = System.currentTimeMillis();
629 | 			file.setLastModified(currentTime);
630 | 			lastUsageDates.put(file, currentTime);
631 | 		}
632 | 
633 | 		private File get(String key) {
634 | 			File file = newFile(key);
635 | 			Long currentTime = System.currentTimeMillis();
636 | 			file.setLastModified(currentTime);
637 | 			lastUsageDates.put(file, currentTime);
638 | 
639 | 			return file;
640 | 		}
641 | 
642 | 		private File newFile(String key) {
643 | 			return new File(cacheDir, key.hashCode() + "");
644 | 		}
645 | 
646 | 		private boolean remove(String key) {
647 | 			File image = get(key);
648 | 			return image.delete();
649 | 		}
650 | 
651 | 		private void clear() {
652 | 			lastUsageDates.clear();
653 | 			cacheSize.set(0);
654 | 			File[] files = cacheDir.listFiles();
655 | 			if (files != null) {
656 | 				for (File f : files) {
657 | 					f.delete();
658 | 				}
659 | 			}
660 | 		}
661 | 
662 | 		/**
663 | 		 * 移除旧的文件
664 | 		 * 
665 | 		 * @return
666 | 		 */
667 | 		private long removeNext() {
668 | 			if (lastUsageDates.isEmpty()) {
669 | 				return 0;
670 | 			}
671 | 
672 | 			Long oldestUsage = null;
673 | 			File mostLongUsedFile = null;
674 | 			Set<Entry<File, Long>> entries = lastUsageDates.entrySet();
675 | 			synchronized (lastUsageDates) {
676 | 				for (Entry<File, Long> entry : entries) {
677 | 					if (mostLongUsedFile == null) {
678 | 						mostLongUsedFile = entry.getKey();
679 | 						oldestUsage = entry.getValue();
680 | 					} else {
681 | 						Long lastValueUsage = entry.getValue();
682 | 						if (lastValueUsage < oldestUsage) {
683 | 							oldestUsage = lastValueUsage;
684 | 							mostLongUsedFile = entry.getKey();
685 | 						}
686 | 					}
687 | 				}
688 | 			}
689 | 
690 | 			long fileSize = calculateSize(mostLongUsedFile);
691 | 			if (mostLongUsedFile.delete()) {
692 | 				lastUsageDates.remove(mostLongUsedFile);
693 | 			}
694 | 			return fileSize;
695 | 		}
696 | 
697 | 		private long calculateSize(File file) {
698 | 			return file.length();
699 | 		}
700 | 	}
701 | 
702 | 	/**
703 | 	 * @title 时间计算工具类
704 | 	 * @author 杨福海(michael) www.yangfuhai.com
705 | 	 * @version 1.0
706 | 	 */
707 | 	private static class Utils {
708 | 
709 | 		/**
710 | 		 * 判断缓存的String数据是否到期
711 | 		 * 
712 | 		 * @param str
713 | 		 * @return true:到期了 false:还没有到期
714 | 		 */
715 | 		private static boolean isDue(String str) {
716 | 			return isDue(str.getBytes());
717 | 		}
718 | 
719 | 		/**
720 | 		 * 判断缓存的byte数据是否到期
721 | 		 * 
722 | 		 * @param data
723 | 		 * @return true:到期了 false:还没有到期
724 | 		 */
725 | 		private static boolean isDue(byte[] data) {
726 | 			String[] strs = getDateInfoFromDate(data);
727 | 			if (strs != null && strs.length == 2) {
728 | 				String saveTimeStr = strs[0];
729 | 				while (saveTimeStr.startsWith("0")) {
730 | 					saveTimeStr = saveTimeStr
731 | 							.substring(1, saveTimeStr.length());
732 | 				}
733 | 				long saveTime = Long.valueOf(saveTimeStr);
734 | 				long deleteAfter = Long.valueOf(strs[1]);
735 | 				if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {
736 | 					return true;
737 | 				}
738 | 			}
739 | 			return false;
740 | 		}
741 | 
742 | 		private static String newStringWithDateInfo(int second, String strInfo) {
743 | 			return createDateInfo(second) + strInfo;
744 | 		}
745 | 
746 | 		private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) {
747 | 			byte[] data1 = createDateInfo(second).getBytes();
748 | 			byte[] retdata = new byte[data1.length + data2.length];
749 | 			System.arraycopy(data1, 0, retdata, 0, data1.length);
750 | 			System.arraycopy(data2, 0, retdata, data1.length, data2.length);
751 | 			return retdata;
752 | 		}
753 | 
754 | 		private static String clearDateInfo(String strInfo) {
755 | 			if (strInfo != null && hasDateInfo(strInfo.getBytes())) {
756 | 				strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1,
757 | 						strInfo.length());
758 | 			}
759 | 			return strInfo;
760 | 		}
761 | 
762 | 		private static byte[] clearDateInfo(byte[] data) {
763 | 			if (hasDateInfo(data)) {
764 | 				return copyOfRange(data, indexOf(data, mSeparator) + 1,
765 | 						data.length);
766 | 			}
767 | 			return data;
768 | 		}
769 | 
770 | 		private static boolean hasDateInfo(byte[] data) {
771 | 			return data != null && data.length > 15 && data[13] == '-'
772 | 					&& indexOf(data, mSeparator) > 14;
773 | 		}
774 | 
775 | 		private static String[] getDateInfoFromDate(byte[] data) {
776 | 			if (hasDateInfo(data)) {
777 | 				String saveDate = new String(copyOfRange(data, 0, 13));
778 | 				String deleteAfter = new String(copyOfRange(data, 14,
779 | 						indexOf(data, mSeparator)));
780 | 				return new String[] { saveDate, deleteAfter };
781 | 			}
782 | 			return null;
783 | 		}
784 | 
785 | 		private static int indexOf(byte[] data, char c) {
786 | 			for (int i = 0; i < data.length; i++) {
787 | 				if (data[i] == c) {
788 | 					return i;
789 | 				}
790 | 			}
791 | 			return -1;
792 | 		}
793 | 
794 | 		private static byte[] copyOfRange(byte[] original, int from, int to) {
795 | 			int newLength = to - from;
796 | 			if (newLength < 0)
797 | 				throw new IllegalArgumentException(from + " > " + to);
798 | 			byte[] copy = new byte[newLength];
799 | 			System.arraycopy(original, from, copy, 0,
800 | 					Math.min(original.length - from, newLength));
801 | 			return copy;
802 | 		}
803 | 
804 | 		private static final char mSeparator = ' ';
805 | 
806 | 		private static String createDateInfo(int second) {
807 | 			String currentTime = System.currentTimeMillis() + "";
808 | 			while (currentTime.length() < 13) {
809 | 				currentTime = "0" + currentTime;
810 | 			}
811 | 			return currentTime + "-" + second + mSeparator;
812 | 		}
813 | 
814 | 		/*
815 | 		 * Bitmap → byte[]
816 | 		 */
817 | 		private static byte[] Bitmap2Bytes(Bitmap bm) {
818 | 			if (bm == null) {
819 | 				return null;
820 | 			}
821 | 			ByteArrayOutputStream baos = new ByteArrayOutputStream();
822 | 			bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
823 | 			return baos.toByteArray();
824 | 		}
825 | 
826 | 		/*
827 | 		 * byte[] → Bitmap
828 | 		 */
829 | 		private static Bitmap Bytes2Bimap(byte[] b) {
830 | 			if (b.length == 0) {
831 | 				return null;
832 | 			}
833 | 			return BitmapFactory.decodeByteArray(b, 0, b.length);
834 | 		}
835 | 
836 | 		/*
837 | 		 * Drawable → Bitmap
838 | 		 */
839 | 		private static Bitmap drawable2Bitmap(Drawable drawable) {
840 | 			if (drawable == null) {
841 | 				return null;
842 | 			}
843 | 			// 取 drawable 的长宽
844 | 			int w = drawable.getIntrinsicWidth();
845 | 			int h = drawable.getIntrinsicHeight();
846 | 			// 取 drawable 的颜色格式
847 | 			Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
848 | 					: Bitmap.Config.RGB_565;
849 | 			// 建立对应 bitmap
850 | 			Bitmap bitmap = Bitmap.createBitmap(w, h, config);
851 | 			// 建立对应 bitmap 的画布
852 | 			Canvas canvas = new Canvas(bitmap);
853 | 			drawable.setBounds(0, 0, w, h);
854 | 			// 把 drawable 内容画到画布中
855 | 			drawable.draw(canvas);
856 | 			return bitmap;
857 | 		}
858 | 
859 | 		/*
860 | 		 * Bitmap → Drawable
861 | 		 */
862 | 		@SuppressWarnings("deprecation")
863 | 		private static Drawable bitmap2Drawable(Bitmap bm) {
864 | 			if (bm == null) {
865 | 				return null;
866 | 			}
867 | 			return new BitmapDrawable(bm);
868 | 		}
869 | 	}
870 | 
871 | }
872 | 


--------------------------------------------------------------------------------