ImageLoader学习笔记

来源:互联网 发布:手机hifi音效软件 编辑:程序博客网 时间:2024/05/21 17:36
/** * Created by Administrator on 2017/6/5 0005. */public class MyImageLoader {    /**     * 如果我们需要加载一个音乐的专辑图片,     * 可以先从内存缓存中去进行该专辑     * 图片的查找,如果内存缓存中没有的话,     * 再从文件缓存中查找,如果文件缓存中也     * 没有的话,说明我们还从来没有网络上加载     * 过要使用的图片,这时我们再从网络上加载     * 加载完成之再分别把这个图片缓存到内存和     * 文件中,以便于下次再使用的时候,可以直接     * 从缓存中拿到。     */    //强引用里的数据是永远不可能被垃圾回收器回收的    //软引用里存的数据在android3.0之后就变的不可靠。    /*LruCache 集合最近最少使用      存在于该集合中的数据都是强引用      我们可以在定义这样的集合时设置一个最大的      存储空间,当空间满了要加新的数据时会根据最近      最少使用的算法    */    public static LruCache<String, Bitmap> lruCacheMemory = null;    static {        int maxSize = (int) Runtime.getRuntime().maxMemory();        lruCacheMemory = new LruCache<String, Bitmap>(maxSize) {            @Override            protected int sizeOf(String key, Bitmap value) {                return value.getHeight() * value.getRowBytes();            }        };    }    /**     * @param context     * @param imageView 专辑图片控件     * @param imageUrl  网络图片的路径     */    public static void setBitmapFromCache(Context context, ImageView imageView, String imageUrl) {        //从缓存中获得的图片        Bitmap bitmap = null;        //判断如果没有提供图片的路径就直接返回        if (TextUtils.isEmpty(imageUrl)) {            return;        }        //先从内存中查找有没有要使用的图片        //如果有直接使用        bitmap = getBitmapFromMemory(imageUrl);        if (bitmap != null) {            //把图片应用到控件上            imageView.setImageBitmap(bitmap);            return;        }        //再从文件缓存中查找有没有要使用的图片        //如果有就直接使用        bitmap = getBitmapFromFile(context, imageUrl);        if (bitmap != null) {            imageView.setImageBitmap(bitmap);            return;        }        //说明使用的图片还没有从网加载过,        //从网络上加载该图片        loadBitmapFromHttp(context, imageView, imageUrl);    }    private static void loadBitmapFromHttp(Context context, ImageView imageView, String imageUrl) {        //要访问网络,实现异步加载        ImageAsyncTask task = new ImageAsyncTask(context, imageView);        //启动异步任务        task.execute(imageUrl);    }    //实现异步图片加载的任务类    private static class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {        private Context context;        private ImageView imageView;        static int imageWidth;        static int imageHeight;        ImageAsyncTask(Context context,                       ImageView imageView) {            this.context = context;            this.imageView = imageView;            ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();            imageWidth = layoutParams.width;            imageHeight = layoutParams.height;        }        @Override        protected Bitmap doInBackground(                String... strings) {            String path = strings[0];            Bitmap bitmap = null;            //构建URL对象            try {                URL url = new URL(path);                HttpURLConnection connection =                        (HttpURLConnection)                                url.openConnection();                connection.setRequestMethod("GET");                connection.setConnectTimeout(5000);                connection.setDoInput(true);                connection.connect();                int statusCode = connection.getResponseCode();                if (statusCode == 200) {                    //获得响应的结果                    InputStream is = connection.getInputStream();                    //bitmap = BitmapFactory.decodeStream(is);                    bitmap = compressBitmap(is, imageWidth, imageHeight);                    //判断该图片是否加载成功                    if (bitmap != null) {                        //将图片缓存到内存中                        lruCacheMemory.put(path, bitmap);                        //将图片缓存到文件中                        saveBitmapToFile(context, path, bitmap);                        return bitmap;                    }                }            } catch (MalformedURLException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }            return null;        }        @Override        protected void onPostExecute(Bitmap bitmap) {            //把图片应用到控件上            imageView.setImageBitmap(bitmap);        }    }    /**     * 压缩图片     * @param is     * @param imageWidth 原始图片宽度     * @param imageHeight 原始图片高度     * @return     */    private static Bitmap compressBitmap(InputStream is, int imageWidth, int imageHeight) {        Bitmap bitmap;        byte[] datas = getBitmapByteArray(is);        BitmapFactory.Options options = new BitmapFactory.Options();        //为true时。只获取尺寸,不获取别的        options.inJustDecodeBounds = true;        BitmapFactory.decodeByteArray(datas, 0, datas.length, options);        //获得原始图片的边界的宽度和高度        int outWidth = options.outWidth;        int outHeight = options.outHeight;        //设置压缩后的宽度和高度,即目标宽高        int targetWidth = imageWidth;        int targetHeight = imageHeight;        //计算宽度方向上的压缩比例        int scaleWidth = outWidth / targetWidth;        //计算高度方向上的压缩比例        int scaleHeight = outHeight / targetHeight;        //最终的比例,拿最大的        int scaleFinal = scaleWidth > scaleHeight ? scaleWidth : scaleHeight;        //特殊情况处理,万一原始图片比目标宽高要小!        if (scaleFinal <= 0) {            scaleFinal = 1;        }        options.inSampleSize = scaleFinal;        options.inJustDecodeBounds = false;        bitmap = BitmapFactory.decodeByteArray(datas, 0, datas.length, options);        return bitmap;    }    /**     * 将输入流转换成字节数组,以供BitmapFactory获取图片的尺寸等信息     *     * @param is     * @return     */    public static byte[] getBitmapByteArray(InputStream is) {        ByteArrayOutputStream os = null;        byte[] datas = null;        try {            os = new ByteArrayOutputStream();            byte[] buffer = new byte[1024];            int len = 0;            while ((len = is.read(buffer)) != -1) {                os.write(buffer, 0, len);            }            os.flush();        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                os.close();                is.close();            } catch (IOException e) {                e.printStackTrace();            }        }        datas = os.toByteArray();        return datas;    }    //将图片缓存到文件中    private static void saveBitmapToFile(Context context, String path, Bitmap bitmap) {        File cacheDir = context.getCacheDir();        if (!cacheDir.exists()) {            cacheDir.mkdir();        }        //获得要缓存的文件的名字        String fileName = path.substring(path.lastIndexOf("/") + 1);        //创建一个文件对象        File file =                new File(cacheDir, fileName);        try {            OutputStream os =                    new FileOutputStream(file);            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }    private static Bitmap getBitmapFromFile(Context context, String imageUrl) {        String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);        File cachDir = context.getCacheDir();        if (cachDir != null) {            for (File file : cachDir.listFiles()) {                if (fileName.equals(file.getName())) {                    //查找到了要使用的图了                    return BitmapFactory.decodeFile(file.getAbsolutePath());                }            }        }        return null;    }    private static Bitmap getBitmapFromMemory(String imageUrl) {        Bitmap bitmap = null;        bitmap = lruCacheMemory.get(imageUrl);        return bitmap;    }}