├── .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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | AsimpleCacheDemo
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/=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 mInstanceMap = new HashMap();
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 lastUsageDates = Collections.synchronizedMap(new HashMap());
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> entries = lastUsageDates.entrySet();
728 | synchronized (lastUsageDates) {
729 | for (Entry 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 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/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 |
7 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
20 |
21 |
27 |
28 |
34 |
35 |
41 |
42 |
48 |
49 |
55 |
56 |
62 |
63 |
69 |
70 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_bitmap.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
20 |
21 |
26 |
27 |
33 |
34 |
38 |
39 |
45 |
46 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_drawable.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
20 |
21 |
26 |
27 |
33 |
34 |
38 |
39 |
45 |
46 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_file.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
20 |
21 |
26 |
27 |
32 |
33 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_jsonarray.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
19 |
20 |
25 |
26 |
31 |
32 |
36 |
37 |
42 |
43 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_jsonobject.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
19 |
20 |
25 |
26 |
31 |
32 |
36 |
37 |
42 |
43 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_object.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
19 |
20 |
25 |
26 |
31 |
32 |
36 |
37 |
42 |
43 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/layout/activity_save_string.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
29 |
30 |
35 |
36 |
40 |
41 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/menu/activity_save_jsonarray.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AsimpleCacheDemo
5 | AsimpleCacheDemo
6 | Settings
7 | SaveDrawableActivity
8 | SaveJsonArrayActivity
9 |
10 |
--------------------------------------------------------------------------------
/AsimpleCacheDemo/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/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 mInstanceMap = new HashMap();
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 lastUsageDates = Collections
574 | .synchronizedMap(new HashMap());
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> entries = lastUsageDates.entrySet();
675 | synchronized (lastUsageDates) {
676 | for (Entry 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 |
--------------------------------------------------------------------------------