<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
activity_main.xml
<Button android:onClick="displayImage" android:text="加载图片" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" />
ImageHelper
//复制就行
public class ImageHelper { private static ImageHelper imageHelper = null; private final LruCache<String, Bitmap> lruCache; public static ImageHelper getInstance() { if (imageHelper == null) { synchronized (ImageHelper.class) { if (imageHelper == null) { imageHelper = new ImageHelper(); } } } return imageHelper; } private ImageHelper() { //初始化内存中存图片需要的lruCache //创建对象的时候就去分配一个内存 //使用LruCache对象进行内存的缓存...底层是LinedHashMap..特点:当内存不够用的时候,可以自动移除最近使用次数最少的对象 //初始化的时候需要指定该缓存的对象能够存储多大的空间...最大内存的1/8....例如:4M int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8); //计算每一张图片 所占空间的大小....lruCache会根据存储的对象的大小跟maxSize进行对比,如果继续再存储一张会超过maxSize,将会使用lru算法删除缓存对象 lruCache = new LruCache<String, Bitmap>(maxSize){ @Override protected int sizeOf(String key, Bitmap value) { //计算每一张图片 所占空间的大小....lruCache会根据存储的对象的大小跟maxSize进行对比,如果继续再存储一张会超过maxSize,将会使用lru算法删除缓存对象 return value.getRowBytes()*value.getHeight(); } }; } public void displayImage(String url, ImageView imageView) { //1.先根据url获取内存中的图片 有,显示图片,结束当前方法的执行 Bitmap bitmap = lruCache.get(url); if (bitmap != null) { Log.e("----","---内存中获取"); imageView.setImageBitmap(bitmap); return; } //2.内存中没有,,,取sd卡中的图片 有,添加到内存,显示图片,,,结束方法向下执行 bitmap = loadFromLocal(url); if (bitmap != null) { Log.e("-----","----sd卡获取"); imageView.setImageBitmap(bitmap); return; } //3.sd卡里面也没有,,,,网络上获取图片,保存到内存,sd卡中,,显示图片 loadFromNet(url,imageView); } /** * 网络上获取 * @param path * @param imageView */ private void loadFromNet(final String path, final ImageView imageView) { Log.e("-----","---网络获取"); //网络上获取图片, AsyncTask<Void, Void, Bitmap> asyncTask = new AsyncTask<Void, Void, Bitmap>() { @Override protected Bitmap doInBackground(Void... voids) { //获取网络数据 try { URL url = new URL(path); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setConnectTimeout(5000); httpURLConnection.setReadTimeout(5000); if (httpURLConnection.getResponseCode() == 200) { InputStream inputStream = httpURLConnection.getInputStream(); //把这个字节流转成bitmap Bitmap bitmap = BitmapFactory.decodeStream(inputStream); return bitmap; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Bitmap bitmap) { // 保存到内存 lruCache.put(path,bitmap); // 写入sd卡中 wrtieToSdCard(path,bitmap); // 显示图片 imageView.setImageBitmap(bitmap); } }; asyncTask.execute(); } /** * 将图片写入sd卡 * @param url http:// * @param bitmap */ private void wrtieToSdCard(String url, Bitmap bitmap) { try { //使用url路径作为保存在sd卡上bitmap的文件名 但是url路径里面有特殊字符 需要编码一下 String path = encodeUrl(url); File file = new File(getCacheDir(), path); FileOutputStream fileOutputStream = new FileOutputStream(file); //把bitmap图片压缩的输出流中,然后存到文件,,,JPEG以图片的格式,,100表示压缩率为0,,,70表示压缩率是30% bitmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream); fileOutputStream.close(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 获取把bitmap存在sd卡中的路径 * @return */ private File getCacheDir() { File dir = null; if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { dir = new File(Environment.getExternalStorageDirectory(),"/CustomCache/pic"); if (! dir.exists()) { dir.mkdirs(); } } return dir; } private String encodeUrl(String url) throws NoSuchAlgorithmException, UnsupportedEncodingException { byte[] hash = MessageDigest.getInstance("MD5").digest(url.getBytes("UTF-8")); StringBuilder hex = new StringBuilder(hash.length * 2); for (byte b : hash) { if ((b & 0xFF) < 0x10) { hex.append("0"); } hex.append(Integer.toHexString(b & 0xFF)); } return hex.toString(); } /** * 本地加载图片...取出sd卡的图片之后 写到内存 * @param url * @return */ private Bitmap loadFromLocal(String url) { try { String path = encodeUrl(url); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File file = new File(getCacheDir(), path); //把file转成bitmap Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); //写入内存 if (bitmap != null) { lruCache.put(url,bitmap); } return bitmap; } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } }
MainActivity
//全局变量
private ImageView imageView;
imageView = findViewById(R.id.image_view);
//按钮点击事件
public void displayImage(View view) { ImageHelper.getInstance().displayImage("http://img5.imgtn.bdimg.com/it/u=937840224,4190645943&fm=27&gp=0.jpg",imageView); }