扣丁学堂——双缓存实例(处理较大网络图片)
2016-01-23 20:24
681 查看
一丶代码见本文
二丶演示(略)就是点击显示网络图片,并将其加载进入缓存和内存中
java没学好,这节还怎么懂,就直接复制粘贴源码,下次慢慢看,用到直接用
MainActivity
LruCacheUtils(磁盘缓存第三方解决方案,这里重新律顺一下)
二丶演示(略)就是点击显示网络图片,并将其加载进入缓存和内存中
java没学好,这节还怎么懂,就直接复制粘贴源码,下次慢慢看,用到直接用
MainActivity
public class MainActivity extends AppCompatActivity { private ImageView iv,iv2; private LruCache<String,Bitmap> lruCache; private LruCacheUtils lruCacheUtils; private static final String DISK_CACHE_SUBDIR = "temp"; private static final int DISK_CACHE_SIZE = 1024*1024*10; //10MB @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.imageView); iv2 = (ImageView) findViewById(R.id.imageView2); //获取当前activity内存大小 ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); int memoryClass = am.getMemoryClass(); final int cacheSize = memoryClass/8 * 1024 * 1024; //字节 8/1的内存作为缓存大小(通常) lruCache = new LruCache<>(cacheSize); } //添加缓存 public void addBitmapToCache(String key,Bitmap bitmap){ if(getBitmapFromCahce(key)==null){ lruCache.put(key,bitmap); } } //从缓存中读取方法 public Bitmap getBitmapFromCahce(String key){ return lruCache.get(key); } public void showClick(View view){ String key = String.valueOf(R.mipmap.a); Bitmap bitmap = getBitmapFromCahce(key); if(bitmap==null) { bitmap = decodeSampledBitmapFromResource(getResources(), R.mipmap.a, 100, 100); addBitmapToCache(key,bitmap); }else{ System.out.println("lruCache中有位图"); } iv.setImageBitmap(bitmap); } public void show2Click(View view){ String url = "http://i2.sinaimg.cn/photo/2/2013-06-17/U10152P1505T2D2F66DT20150328095931.jpg"; loadBitmap(url,iv2); } @Override protected void onResume() { super.onResume(); lruCacheUtils = LruCacheUtils.getInstance(); lruCacheUtils.open(this, DISK_CACHE_SUBDIR, DISK_CACHE_SIZE); } @Override protected void onPause() { super.onPause(); lruCacheUtils.flush(); } @Override protected void onStop() { super.onStop(); lruCacheUtils.close(); } /** * 加载图片 * @param url * @param imageView */ public void loadBitmap(String url, final ImageView imageView){ //从内存缓存中取图片 Bitmap bitmap = lruCacheUtils.getBitmapFromCahce(url); if (bitmap==null){ //再从磁盘缓存中取图片 InputStream in = lruCacheUtils.getDiskCache(url); if (in==null){ lruCacheUtils.putCache(url, new LruCacheUtils.CallBack<Bitmap>() { @Override public void response(Bitmap entity) { System.out.println("http load"); imageView.setImageBitmap(entity); } }); }else{ System.out.println("disk cache"); bitmap = BitmapFactory.decodeStream(in); lruCacheUtils.addBitmapToCache(url,bitmap); imageView.setImageBitmap(bitmap); } }else{ System.out.println("memory cache"); imageView.setImageBitmap(bitmap); } } /** * 位图重新采样 * @param res * @param resid * @param reqWidth * @param reqHeight * @return */ public Bitmap decodeSampledBitmapFromResource(Resources res,int resid,int reqWidth,int reqHeight){ BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res,resid,options); options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight); options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resid,options); } /** * 计算位图的采样比例 * @param options * @param reqWidth * @param reqHeight * @return */ public int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){ //获取位图的原宽高 int w = options.outWidth; int h = options.outHeight; System.out.println("w="+w); System.out.println("h="+h); int inSampleSize = 1; if(w>reqWidth || h>reqHeight){ if(w>h){ // Math.round四舍五入 inSampleSize = Math.round((float)h / (float)reqHeight); }else{ inSampleSize = Math.round((float)w / (float)reqWidth); } } System.out.println("inSampleSize="+inSampleSize); return inSampleSize; } }
LruCacheUtils(磁盘缓存第三方解决方案,这里重新律顺一下)
public class LruCacheUtils { private static LruCacheUtils lruCacheUtils; private DiskLruCache diskLruCache; //LRU磁盘缓存 private LruCache<String,Bitmap> lruCache; //LRU内存缓存 private Context context; private LruCacheUtils(){} public static LruCacheUtils getInstance(){ if (lruCacheUtils ==null){ lruCacheUtils = new LruCacheUtils(); } return lruCacheUtils; } //打开磁盘缓存 public void open(Context context,String disk_cache_subdir,int disk_cache_size){ try { this.context = context; //获取当前activity内存大小 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); int memoryClass = am.getMemoryClass(); lruCache = new LruCache<>(memoryClass/8 * 1024 * 1024);//字节 8/1的内存作为缓存大小(通常) //open()方法接收四个参数,第一个参数指定的是数据的缓存地址, // 第二个参数指定当前应用程序的版本号, // 第三个参数指定同一个key可以对应多少个缓存文件,基本都是传1, // 第四个参数指定最多可以缓存多少字节的数据。通常10MB diskLruCache = DiskLruCache.open(getCacheDir(disk_cache_subdir), getAppVersion(), 1, disk_cache_size); } catch (IOException e) { e.printStackTrace(); } } //添加缓存 public void addBitmapToCache(String url,Bitmap bitmap){ String key = hashKeyForDisk(url); if(getBitmapFromCahce(key)==null){ System.out.println("key===="+key); System.out.println("bitmap===="+bitmap); lruCache.put(key,bitmap); } } //从缓存中读取方法 public Bitmap getBitmapFromCahce(String url){ String key = hashKeyForDisk(url); return lruCache.get(key); } //关闭磁盘缓存 public void close(){ if (diskLruCache!=null && !diskLruCache.isClosed()){ try { diskLruCache.close(); } catch (IOException e) { e.printStackTrace(); } } } //刷新磁盘缓存 public void flush(){ if (diskLruCache!=null){ try { diskLruCache.flush(); } catch (IOException e) { e.printStackTrace(); } } } /** * 获取磁盘缓存 * @param url * @return */ public InputStream getDiskCache(String url) { String key = hashKeyForDisk(url); System.out.println("getDiskCache="+key); try { DiskLruCache.Snapshot snapshot = diskLruCache.get(key); System.out.println(snapshot); if (snapshot!=null){ return snapshot.getInputStream(0); } } catch (IOException e) { e.printStackTrace(); } return null; } /** * 下载图片并缓存到内存和磁盘 * @param url * @param callBack */ public void putCache(final String url, final CallBack callBack){ new AsyncTask<String,Void,Bitmap>(){ @Override protected Bitmap doInBackground(String... params) { String key = hashKeyForDisk(params[0]); System.out.println("key="+key); DiskLruCache.Editor editor = null; Bitmap bitmap = null; try { URL url = new URL(params[0]); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(1000 * 30); conn.setConnectTimeout(1000 * 30); ByteArrayOutputStream baos = null; if(conn.getResponseCode()==HttpURLConnection.HTTP_OK){ BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); baos = new ByteArrayOutputStream(); byte[] bytes = new byte[1024]; int len = -1; while((len=bis.read(bytes))!=-1){ baos.write(bytes,0,len); } bis.close(); baos.close(); conn.disconnect(); } if (baos!=null){ bitmap = decodeSampledBitmapFromStream(baos.toByteArray(),100,100); addBitmapToCache(params[0],bitmap); editor = diskLruCache.edit(key); System.out.println(url.getFile()); //位图压缩后输出(参数:压缩格式,质量(100表示不压缩,30表示压缩70%),输出流) bitmap.compress(Bitmap.CompressFormat.JPEG, 100, editor.newOutputStream(0)); editor.commit();//提交 } } catch (IOException e) { try { editor.abort();//放弃写入 } catch (IOException e1) { e1.printStackTrace(); } } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); callBack.response(bitmap); } }.execute(url); } //回调接口 public interface CallBack<T>{ public void response(T entity); } /** * 计算采样比例 * @param options * @param reqWidth * @param reqHeight * @return */ public int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){ //获取位图的原宽高 int w = options.outWidth; int h = options.outHeight; int inSampleSize = 1; if(w>reqWidth || h>reqHeight){ if(w>h){ inSampleSize = Math.round((float)h / (float)reqHeight); }else{ inSampleSize = Math.round((float)w / (float)reqWidth); } } return inSampleSize; } /** * * @param bytes * @param reqWidth * @param reqHeight * @return */ public Bitmap decodeSampledBitmapFromStream(byte[] bytes,int reqWidth,int reqHeight){ BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight); options.inJustDecodeBounds = false; return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); } /** * MD5计算摘要 * @param key * @return */ public String hashKeyForDisk(String key) { String cacheKey; try { final MessageDigest mDigest = MessageDigest.getInstance("MD5"); mDigest.update(key.getBytes()); cacheKey = bytesToHexString(mDigest.digest()); } catch (NoSuchAlgorithmException e) { cacheKey = String.valueOf(key.hashCode()); } return cacheKey; } private String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xFF & bytes[i]); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); } /** * 获取版本号 * @return */ private int getAppVersion() { try { return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return 1; } //获取缓存目录 private File getCacheDir(String name) { String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED || !Environment.isExternalStorageRemovable() ? context.getExternalCacheDir().getPath() : context.getCacheDir().getPath(); name = cachePath + File.separator + name; System.out.println(name); return new File(name); } }
相关文章推荐
- linux基础网络设置
- XMPP介绍三:Socket
- 基于socket的TCP、UDP 编程(附带源代码)
- 网络基本功系列:概述
- tcpip转
- 利用NET HUNTER建立一个自动文件下载的网络接入点
- ASP.NET Core 1.0 部署 HTTPS
- 利用NET HUNTER建立一个自动文件下载的网络接入点
- Ettercap结合sslstrip对ssl/https进行攻击
- Ettercap结合sslstrip对ssl/https进行攻击
- Glusterfs由RDMA切换到TCP
- AFNetworking网络请求失败
- ASP.NET Core 1.0 部署 HTTPS (.NET Framework 4.5.1)
- android 网络请求库的比较
- HttpPost 传输Json数据并解析
- 关于TCP粘包和半包的处理
- 一种后台网络服务器模型
- java.net.UnknownHostException:www.xxx.com httpclient
- HTTP协议细节
- Mac OS 下监听/拦截 TCP/UDP 连接