ImageLoader学习笔记


/**
 * 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;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值