android 缓存书记,Android中内存缓存和文件缓存的实现原理

MemoryCache内存缓存类讲解

内存缓存即把数据保存在内存中,如果缓存的数据超过设定的内存限制就删除最先缓存进来的数据。下面的MemoryCache缓存类是先创建一个Map对象(这里缓存的是Bitmap数据,所以Map的值为Bitmap),把缓存数据存入这个map对象中,想缓存数据时调用put(String id,Bitmap bitmap)方法,想从内存缓存中取数据时调用 get(String id)。

get(String id)方法的原理是先通过判断cache对象中是否包含要得到的键,如果包含就返回该键对应的值,如果不包含返回null。

put(String id,Bitmap bitmap)方法判断是否包含该键,如果包含,缓存中图片所占用的字节的值需要将该键对应的bitmap对象所占用的内存减掉,再将该bitmap加入到cache对象中,检查现在的缓存的内存值即调用checkSize方法。checkSize方法中计算内存是否超过设定的值,如果超过了,就从cache对象中移除最先缓存的对象

内存缓存类MemoryCache代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

public

class

MemoryCache {

private

static

final

String TAG =

"MemoryCache"

;

/**放入缓存时是个同步操作

*LinkedHashMap构造方法的最后一个参数true代表这个map里的元素将按照最

*近使用次数由少到多排列,即LRU。

*这样的好处是如果要将缓存中的元素替换,则先遍历出最近最少使用的元素来替换以提高效率*/

private

Map cache = Collections

.synchronizedMap(

new

LinkedHashMap(

10

,

1

.5f,

true

));

// 缓存中图片所占用的字节,初始0,将通过此变量严格控制缓存所占用的堆内存

private

long

size =

0

;

// current allocated size

// 缓存只能占用的最大堆内存

private

long

limit =

1000000

;

// max memory in bytes

public

MemoryCache() {

// use 25% of available heap size

setLimit(Runtime.getRuntime().maxMemory() /

4

);

}

public

void

setLimit(

long

new_limit) {

limit = new_limit;

Log.i(TAG,

"MemoryCache will use up to "

+ limit /

1024

. /

1024

. +

"MB"

);

}

public

Bitmap get(String id) {

try

{

if

(!cache.containsKey(id))

return

null

;

return

cache.get(id);

}

catch

(NullPointerException ex) {

return

null

;

}

}

public

void

put(String id, Bitmap bitmap) {

try

{

if

(cache.containsKey(id))

size -= getSizeInBytes(cache.get(id));

cache.put(id, bitmap);

size += getSizeInBytes(bitmap);

checkSize();

}

catch

(Throwable th) {

th.printStackTrace();

}

}

/**

* 严格控制堆内存,如果超过将首先替换最近最少使用的那个图片缓存

*

*/

private

void

checkSize() {

Log.i(TAG,

"cache size="

+ size +

" length="

+ cache.size());

if

(size > limit) {

// 先遍历最近最少使用的元素

Iterator> iter = cache.entrySet().iterator();

while

(iter.hasNext()) {

Entry entry = iter.next();

size -= getSizeInBytes(entry.getValue());

iter.remove();

if

(size <= limit)

break

;

}

Log.i(TAG,

"Clean cache. New size "

+ cache.size());

}

}

public

void

clear() {

cache.clear();

}

/**

* 图片占用的内存

*

* @param bitmap

* @return

*/

long

getSizeInBytes(Bitmap bitmap) {

if

(bitmap ==

null

)

return

0

;

return

bitmap.getRowBytes() * bitmap.getHeight();

}

}

使用SoftReference做的内存缓存类

也可以使用SoftReference,代码会简单很多,不过我们推荐使用上面的一种方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

public

class

MemoryCache {

private

Map> cache = Collections

.synchronizedMap(

new

HashMap>());

public

Bitmap get(String id) {

if

(!cache.containsKey(id))

return

null

;

SoftReference ref = cache.get(id);

return

ref.get();

}

public

void

put(String id, Bitmap bitmap) {

cache.put(id,

new

SoftReference(bitmap));

}

public

void

clear() {

cache.clear();

}

}

文件缓存类FileCache讲解

文件缓存类的作用也就是把文件保存到SD卡上,下面是文件缓存类的代码FileCache.java:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

public

class

FileCache {

private

File cacheDir;

public

FileCache(Context context) {

// 如果有SD卡则在SD卡中建一个LazyList的目录存放缓存的图片

// 没有SD卡就放在系统的缓存目录中

if

(android.os.Environment.getExternalStorageState().equals(

android.os.Environment.MEDIA_MOUNTED))

cacheDir =

new

File(

android.os.Environment.getExternalStorageDirectory(),

"LazyList"

);

else

cacheDir = context.getCacheDir();

if

(!cacheDir.exists())

cacheDir.mkdirs();

}

public

File getFile(String url) {

// 将url的hashCode作为缓存的文件名

String filename = String.valueOf(url.hashCode());

// Another possible solution

// String filename = URLEncoder.encode(url);

File f =

new

File(cacheDir, filename);

return

f;

}

public

void

clear() {

File[] files = cacheDir.listFiles();

if

(files ==

null

)

return

;

for

(File f : files)

f.delete();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值