废话不多说,直接贴代码!
所谓的双缓存,第一就是缓存在内存里面,第二就是缓存在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; }