转载地址:http://www.2cto.com/kf/201502/376042.html
1,LruCache介绍
核心的类是LruCache (此类在android-support-v4的包中提供) 。这个类非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。
在过去,我们经常会使用一种非常流行的内存缓存技术的实现,即软引用或弱引用 (SoftReference or WeakReference)。但是现在已经不再推荐使用这种方式了,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。另外,Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,这就有潜在的风险造成应用程序的内存溢出并崩溃。
2,LruCache使用 下面我们就来写一个简单的demo来学习LruCache,效果也是每次请求一次第二次直接从缓存中提取出来不用再次请求网络
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
|
/**
* 缓存json数据
*/
private
LruCache<integer, string=
""
> mJsonCache;
/**
* 缓存图片信息
*/
private
LruCache<integer, bitmap=
""
> mBitmapCache;
public
Util() {
mJsonCache =
new
LruCache<integer, string=
""
>(
1
*
1024
*
1024
);
mBitmapCache =
new
LruCache<integer, bitmap=
""
>(
2
*
1024
*
1024
);
}
/**
* 添加进入缓存列表
*
* @param key
* @param value
*/
public
void
addJsonLruCache(Integer key, String value) {
mJsonCache.put(key, value);
}
public
void
addBitmapLruCache(Integer key, Bitmap value) {
mBitmapCache.put(key, value);
}
/**
* 从缓存列表中拿出来
*
* @param key
* @return
*/
public
String getJsonLruCache(Integer key) {
return
mJsonCache.get(key);
}
public
Bitmap getBitmapLruCache(Integer key) {
return
mBitmapCache.get(key);
}</integer,></integer,></integer,></integer,>
|
可以看到我们准备缓存Bitmap与String,只需要拿到信息的时候put进缓存中,需要的时候get出来,是不是非常简单,我们为我们String分配了1m为我们的Bitmap分配了2m空间,这只是我们的demo为了简单这样使用,实际上我们应该更加详细的考虑到底应该为缓存分配多大的空间
1
2
3
|
// 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。
// LruCache通过构造函数传入缓存值,以KB为单位。
int
maxMemory = (
int
) (Runtime.getRuntime().maxMemory() /
1024
);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
MainActivity
extends
Activity
implements
OnItemClickListener {
private
static
final
String LIST_DATA = http:
//api.yi18.net/top/list;
private
ListView mListView;
private
ArrayAdapter<string> mAdapter;
private
ArrayList<integer> mListId;
private
Util util;
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
util =
new
Util();
mListView = (ListView) findViewById(R.id.list);
mListId =
new
ArrayList<integer>();
mAdapter =
new
ArrayAdapter<string>(
this
,
android.R.layout.simple_list_item_1);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(
this
);
new
DownLoadJson().execute(LIST_DATA);
}</string></integer></integer></string>
|
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
|
private
void
getJsonData(String json) {
try
{
JSONObject jsonObject =
new
JSONObject(json);
if
(jsonObject.getBoolean(success)) {
JSONArray jsonArray = jsonObject.getJSONArray(yi18);
for
(
int
i =
0
; i < jsonArray.length(); i++) {
JSONObject jsonObject2 = (JSONObject) jsonArray.opt(i);
if
(i <
5
) {
mAdapter.add(jsonObject2.getString(title));
mListId.add(jsonObject2.getInt(id));
}
}
}
}
catch
(JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class
DownLoadJson
extends
AsyncTask<string, string=
""
> {
@Override
protected
String doInBackground(String... params) {
return
util.downLoadJson(params[
0
]);
}
@Override
protected
void
onPostExecute(String result) {
if
(result !=
null
) {
getJsonData(result);
}
}
}</string,>
|
![data-cke-saved-src=http://www.2cto.com/uploadfile/Collfiles/20150207/20150207084912191.png](http://www.2cto.com/uploadfile/Collfiles/20150207/20150207084912191.png)
我们就简单的取了前五条数据用来模拟我们的新闻,用的是热点热词的Api。
3,缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Override
public
void
onItemClick(AdapterView<!--?--> arg0, View arg1,
int
arg2,
long
arg3) {
// TODO Auto-generated method stub
String message = util.getJsonLruCache(mListId.get(arg2));
Bitmap bitmap = util.getBitmapLruCache(mListId.get(arg2));
if
(message !=
null
) {
intentNewsInfo(arg2, message, bitmap);
}
else
{
intentNewsInfo(arg2,
null
,
null
);
}
}
public
void
intentNewsInfo(
int
arg2, String message, Bitmap bitmap) {
Intent intent =
new
Intent(MainActivity.
this
, NewsinfoActivity.
class
);
intent.putExtra(message, message);
intent.putExtra(bitmap, bitmap);
intent.putExtra(index, arg2);
intent.putExtra(id, mListId.get(arg2));
startActivityForResult(intent,
100
);
}
|
可以看到我们这里先是查找缓存中是否存在数据如果存在直接传给新闻详情界面,如果没有则在第二个界面获取再传回来。
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
public
class
NewsinfoActivity
extends
Activity {
private
String NEWS_INFO = http:
//api.yi18.net/top/show?id=;
private
String imageRes[] = {
http:
//d.hiphotos.baidu.com/image/h%3D360/sign=405b763459afa40f23c6c8db9b65038c/562c11dfa9ec8a13508c96e6f403918fa0ecc026.jpg,
http:
//c.hiphotos.baidu.com/image/h%3D360/sign=798b4f82caea15ce5eeee60f86013a25/9c16fdfaaf51f3dece3f986397eef01f3a297923.jpg,
http:
//f.hiphotos.baidu.com/image/h%3D360/sign=20a94e03940a304e4d22a6fce1c9a7c3/ac4bd11373f082028719ab3848fbfbedab641b29.jpg,
http:
//b.hiphotos.baidu.com/image/h%3D360/sign=3a1af7349145d688bc02b4a294c37dab/4b90f603738da977c0f5b82cb351f8198718e3db.jpg,
http:
//d.hiphotos.baidu.com/image/h%3D360/sign=75e596560f33874483c5297a610ed937/55e736d12f2eb9381891b2f4d6628535e5dd6f3c.jpg };
private
Intent intent;
private
Util util;
private
int
newId, index;
private
ImageView imageView;
private
TextView textView;
private
Bitmap bitmap;
private
String message;
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_newsinfo);
intent = getIntent();
util =
new
Util();
imageView = (ImageView) findViewById(R.id.image);
textView = (TextView) findViewById(R.id.message);
newId = intent.getExtras().getInt(id);
index = intent.getExtras().getInt(index);
if
(intent.getExtras().getString(message) !=
null
) {
message = intent.getExtras().getString(message);
bitmap = intent.getParcelableExtra(bitmap);
textView.setText(Html.fromHtml(message));
imageView.setImageBitmap(bitmap);
Toast.makeText(
this
, 没有访问网络哦,
2000
).show();
}
else
{
new
DownLoadJson().execute(NEWS_INFO + newId);
new
DownLoadBitmap().execute(imageRes[index]);
Toast.makeText(
this
, 访问网络哦,
2000
).show();
}
}
@Override
public
void
onBackPressed() {
Intent dataIntent =
new
Intent();
dataIntent.putExtra(message, message);
dataIntent.putExtra(bitmap, bitmap);
dataIntent.putExtra(newId, newId);
setResult(
20
, dataIntent);
finish();
super
.onBackPressed();
}
private
void
getJsonData(String json) {
try
{
JSONObject jsonObject =
new
JSONObject(json);
if
(jsonObject.getBoolean(success)) {
JSONObject jsonObject2 =
new
JSONObject(
jsonObject.getString(yi18));
message = jsonObject2.getString(message);
textView.setText(Html.fromHtml(jsonObject2.getString(message)));
}
}
catch
(JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class
DownLoadJson
extends
AsyncTask<string, string=
""
> {
@Override
protected
String doInBackground(String... params) {
return
util.downLoadJson(params[
0
]);
}
@Override
protected
void
onPostExecute(String result) {
if
(result !=
null
) {
getJsonData(result);
}
}
}
class
DownLoadBitmap
extends
AsyncTask<string, bitmap=
""
> {
@Override
protected
Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
return
util.downLoadBitmap(params[
0
]);
}
@Override
protected
void
onPostExecute(Bitmap result) {
if
(result !=
null
) {
bitmap = result;
imageView.setImageBitmap(result);
}
}
}
}</string,></string,>
|
这就比较清晰明白了,每次我们都把这个界面获取到的信息存到LruCache里面。
1
2
3
4
5
6
7
8
9
|
@Override
protected
void
onActivityResult(
int
requestCode,
int
resultCode, Intent data) {
int
newId = data.getExtras().getInt(newId);
String message = data.getExtras().getString(message);
Bitmap bitmap = data.getParcelableExtra(bitmap);
util.addJsonLruCache(newId, message);
util.addBitmapLruCache(newId, bitmap);
super
.onActivityResult(requestCode, resultCode, data);
}
|
4,效果