你的位置:首页 > 操作系统

[操作系统]android 双缓存机制


废话不多说,直接贴代码!

所谓的双缓存,第一就是缓存在内存里面,第二就是缓存在SD卡里面,当你需要加载数据时,先去内存缓存中查找,如果没有再去SD卡中查找,并且用户可以自选使用哪种缓存!

缓存内存和缓存SD都有一个共同的方法,就是put和get方法(存数据和取数据),因此我们采用工厂模式!

新建一个接口,名字随便取,用来封装内存缓存和sd缓存里面共有的方法,然后新建一个内存缓存类和sd缓存类,双缓存类并且都实现此接口,注意建双缓存类只是为了更方便的使用其他两个缓存,你想想

如果两个缓存类封装到一个类中,并且这种类中会有判断如何使用哪种缓存,这样就减少了你每次调用哪种缓存就要修改代码的过程了!

package com.example.imageload;

import android.graphics.Bitmap;

/*接口/

public interface MemoryCache {

public Bitmap get(String url);
public void put(String url ,Bitmap bitmap);
}

/*双缓存类

* android双向缓存,
* 先缓存到内存,在缓存到SD卡
* 取的时候先取内存,如果内存没有就去SD里面取
*/
public class DoubleCache implements MemoryCache{
private MemoryCache cache = new ImageCache();//内存缓存
private MemoryCache diskCache = new DiskCache();//SD开缓存

public Bitmap get(String uri){
Bitmap bm = cache.get(uri);

if(bm == null){
bm = diskCache.get(uri);

}
return bm;
}
public void put(String url,Bitmap bitmap){

cache.put(url, bitmap);
diskCache.put(url, bitmap);
}
}

/*内存缓存类/

public class ImageCache implements MemoryCache{
//图片缓存
LruCache<String, Bitmap> mImageCache;

public ImageCache() {
initImageCache();
}
/**
* bitmap.getRowBytes():计算位图每一行占用的字节数
*
*/
private void initImageCache() {
final int maxMemory = (int)Runtime.getRuntime().maxMemory()/1024;

int cacheSize = maxMemory/4;
mImageCache = new LruCache<String, Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap bitmap) {

return bitmap.getRowBytes()*bitmap.getHeight()/1024;
}
};
}
public Bitmap get(String uri){
return mImageCache.get(uri);
}
public void put(String uri,Bitmap bitmap){

mImageCache.put(uri, bitmap);
}
}

/*sd卡缓存类/

public class DiskCache implements MemoryCache{
private String cacheDir = "/data/data/com.example.day8_12/files/"; //存储目录自己选择
/**
* @param url 存放图片的路径名称
* @return 返回位图,如果没有就返回0
*/
public Bitmap get(String url){

return BitmapFactory.decodeFile(cacheDir+setUrl(url));
}
public String setUrl(String url){
int b1 = url.lastIndexOf("/");
String cc = url.substring(b1+1);

return cc;
}
public void put(String url ,Bitmap bitmap){
File settings = new File(cacheDir,setUrl(url));

if (!settings.exists()) {
try {
settings.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return;
}
}

FileOutputStream fileInputStream = null;
try {
fileInputStream = new FileOutputStream(settings);

bitmap.compress(CompressFormat.PNG, 100, fileInputStream);
fileInputStream.flush();
} catch (Exception e) {
Log.i("TAG", "EEEEE"+e.getMessage());
e.printStackTrace();
}finally{
if(fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

/*最后就是显示图片的类/

public class ImageLoader {

ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private MemoryCache cache = new DiskCache();
private Activity activity;
public void setImageCache(MemoryCache memoryCache){
this.cache = memoryCache ;
}
public ImageLoader(Activity activity) {
this.activity = activity;
}
public void displayImage(final String imageurl,final ImageView imageview){
Bitmap bmp = cache.get(imageurl);
if(bmp != null){
imageview.setImageBitmap(bmp);
return;
}
imageview.setTag(imageurl);
service.submit(new Runnable() {
@Override
public void run() {
final Bitmap bitmap = downloadImage(imageurl);
if(bitmap == null){
Log.i("TAG", "0000"+ bitmap);
return;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//这是为了匹配uri跟imagview是一对的
if(imageview.getTag().equals(imageurl)){
imageview.setImageBitmap(bitmap);
}
cache.put(imageurl, bitmap);
}
});
}
});

}
public Bitmap downloadImage (String imageurl) {
Bitmap bitmap = null;
try {
URL url = new URL(imageurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(1000);
bitmap = BitmapFactory.decodeStream(connection.getInputStream());
connection.disconnect();
} catch (Exception e) {
Log.i("TAG", "123::"+e.getMessage());
e.printStackTrace();
}
return bitmap;
}

最后记得加上权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

在MainActivity里面调用如下:

public class MainActivity extends Activity {

private ImageView iamge;
private List<String> list = new ArrayList<String>();
private ImageLoader imageLoader = new ImageLoader(MainActivity.this);
private Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Drawable image = getResources().getDrawable(R.drawable.ic_launcher);
button1 = (Button)findViewById(R.id.button1);

iamge = (ImageView)findViewById(R.id.iamge);

imageLoader.setImageCache(new DoubleCache());

list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy009.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy011.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy085.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy064.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy026.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy150.jpg");
list.add("http://192.168.58.112:1918/hotel/public/upload/video/dy050.jpg");
button1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

Intent intent = new Intent(MainActivity.this,AMainActivity.class);
startActivity(intent);
}
});

}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
imageLoader.displayImage(list.get(0), iamge);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}