Android 加载网络图片并做缓存

标签: 图像处理 android 图片
474人阅读 评论(0) 收藏 举报
分类:
                                                

                             使用Volley获取网络图片,并作本地缓存

          

               Volley是谷歌公司提供的一个框架,主要用于网络请求和图片加载的功能,今天一个初入Android不久的朋友问到我关于加载网络图片怎么做边整理了一下做个记录。

               获取网络图片有多重方法这里主要讲两种:

                      第一种是ImageRequest没做缓存,

                      第二种是ImageLoader毕竟就这两种常用。



第一种是适用于需要实时更新的图片:

              和网络请求类似:

             第一步都是创建请求队列

             第二步创建ImageRequest对象

             第三步将imagerequst对象加入请求队列中

直接上代码:

       

/**
 * @param  context   上下文对象
 * @param  url       网络图片地址
 * @param  singleImg  需要显示的imageview
 */
private void showPicByVolleyRequest(Context context, String url,final ImageView singleImg){
    RequestQueue mQueue = Volley.newRequestQueue(context);
    ImageRequest imageRequest = new ImageRequest(url,
            new Response.Listener<Bitmap>() {
                @Override
                public void onResponse(Bitmap bitmap) {
                    // TODO Auto-generated method stub
                    singleImg.setImageBitmap(bitmap);
                }
            }, 300, 200, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError e) {
            e.printStackTrace();
        }
    });
    mQueue.add(imageRequest);
}
     

第二种是适用于需要实时更新的图片:

              和网络请求类似:

             第一步都是创建请求队列

             第二步创建ImageLoader对象

             第三步通过imageloader展示图片


       其中为了缓存图片我们需要自己去继承 ImageCache这个类并在里面设置缓存参数


   先上实现了ImageCache的类,里面对参数进行了详细的描述:

package com.example.contentprovide;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.text.TextUtils;
import android.util.LruCache;

import com.android.volley.toolbox.ImageLoader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by Administrator on 2017/8/25.
 */

public class BitmapCache implements ImageLoader.ImageCache {

    private LruCache<String, Bitmap> mCache;

    public BitmapCache() {
        int maxSize = 10 * 1024 * 1024;
        mCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }

    /**
     * 先从缓存中找,有则返回图片,没有则从网络获取 
     */
    @Override
    public Bitmap getBitmap(String url) {
        /**
         * 先从缓存中找,有则返回,没有则返回null 
         */
        Bitmap bitmap = mCache.get(url);

        if (bitmap == null) {
            String fileName = url.substring(url.lastIndexOf("/") + 1);
            /**
             * 如果为null,则缓存中没有,从本地SD卡缓存中找 
             */
            File cacheDir = new File(getSDPath());
            File[] cacheFiles = cacheDir.listFiles();
            if (cacheFiles != null) {
                int i = 0;
                for (; i < cacheFiles.length; i++) {
                    if (TextUtils.equals(fileName, cacheFiles[i].getName()))
                        break;
                }
                /**
                 * 若找到则返回bitmap否则返回null 
                 */
                if (i < cacheFiles.length) {
                    bitmap = getSDBitmap(getSDPath() + "/"
                            + fileName);
                    /**
                     * 将从SD卡中获取的bitmap放入缓存中 
                     */
                    mCache.put(url, bitmap);
                }
            }
        }
        return bitmap;
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        /**
         * 放入缓存中 
         */
        mCache.put(url, bitmap);
        /**
         * 存到本地SD中 
         */
        putSDBitmap(url.substring(url.lastIndexOf("/") + 1), bitmap);
    }

    /**
     * 从本地SD卡中获取图片 
     *
     * @param imgPath
     *            图片路径 
     * @return 图片的Bitmap
     */
    private Bitmap getSDBitmap(String imgPath) {
        Bitmap bm = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        /**
         * 设置临时缓存大小 
         */
        options.inTempStorage = new byte[1024 * 1024];
        /**
         * 通过设置Options.inPreferredConfig值来降低内存消耗: 默认为ARGB_8888: 每个像素4字节. 共32位。 
         * Alpha_8: 只保存透明度,共8位,1字节。 ARGB_4444: 共16位,2字节。 RGB_565:共16位,2字节 
         */
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        /**
         * inPurgeable:设置为True,则使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间, 
         * 在系统内存不足时可以被回收,当应用需要再次访问该Bitmap的Pixel时,系统会再次调用BitmapFactory 
         * 的decode方法重新生成Bitmap的Pixel数组。 设置为False时,表示不能被回收。 
         */
        options.inPurgeable = true;
        options.inInputShareable = true;
        /**
         * 设置decode时的缩放比例。 
         */
        options.inSampleSize = 1;
        bm = BitmapFactory.decodeFile(imgPath, options);
        return bm;
    }
    /**
     *获取sd卡的的路径
     ***/
    public String getSDPath(){
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState()
                .equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在  
        if (sdCardExist)
        {
            sdDir = Environment.getExternalStorageDirectory();//获取跟目录  
        }
        return sdDir.toString();
    }
    /**
     * 将图片保存到本地的SD卡中 
     *
     * @param fileName
     * @param bitmap
     */
    private void putSDBitmap(final String fileName, final Bitmap bitmap) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                File cacheDir = new File(getSDPath());
                if (!cacheDir.exists())
                    cacheDir.mkdirs();
                File cacheFile = new File(getSDPath() + "/"
                        + fileName);
                if (!cacheFile.exists()) {
                    try {
                        cacheFile.createNewFile();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                FileOutputStream fos;
                try {
                    fos = new FileOutputStream(cacheFile);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}


 实现了缓存的了并配置好了参数就该展示我们的网络图片了:

 

 /**
     * @param  context   上下文对象
     * @param  url       网络图片地址
     * @param  singleImg  需要显示的imageview
     */
    private void showPicByVolleyImageLoader(Context context, String url,final ImageView singleImg){
        RequestQueue mQueue = Volley.newRequestQueue(context);
        ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
//        第一个参数指定用于显示图片的ImageView控件,
//        第二个参数指定加载图片的过程中显示的图片,
//        第三个参数指定加载图片失败的情况下显示的图
        ImageLoader.ImageListener listener = ImageLoader.getImageListener(singleImg,
                R.mipmap.ic_launcher,  R.mipmap.ic_launcher);
        imageLoader.get(url, listener);
         //后面的两个参数表示图片大小
        imageLoader.get(url,listener, 200, 200);

    }

  最后的get方法是重载了的,你可以选择不设置图片的宽高。这样你就实现了图片缓存 当你第一次加载好了以后下次断开网络一样能显示出来。


















查看评论

Volley二次封装,实现网络请求缓存

Android目前很多同学使用Volley请求网络数据,但是Volley没有对请求过得数据进行缓存,因此需要我们自己手动缓存。 一下就是我的一种思路,仅供参考 NetWorkHelper---对...
  • zxm317122667
  • zxm317122667
  • 2015-11-04 11:13:16
  • 4865

Android之网络图片加载的5种基本方式

学了这么久,最近有空把自己用到过的网络加载图片的方式总结了出来,与大家共享,希望对你们有帮助。此博客包含Android 5种基本的加载网络图片方式,包括普通加载HttpURLConnection、Ht...
  • DickyQie
  • DickyQie
  • 2017-03-01 21:13:16
  • 9189

Android加载网络图片学习过程

一、最简单加载网络图片 从网络上取图片数据,显示在应用中,简单不赘述: [java] view plaincopy       try {  ...
  • zml_2015
  • zml_2015
  • 2015-10-07 09:18:18
  • 1906

Android之Volley框架加载网络图片的三种方式

1.第一种也是最常用的一种:ImageLoader public void imageLoader(String url,ImageView iv){ //ImageLoader的第一...
  • ygd1994
  • ygd1994
  • 2016-05-08 23:18:28
  • 1353

Android利用HTTP协议加载网络图片

给出一张图片的网址,我们怎么把这张图片加载到我们的ImageView控件显示呢? 由于采用网络请求,我们必须在AndroidManifest.xml添加权限 由于是网络请求数据,我们必须在开辟一条线程...
  • u010214991
  • u010214991
  • 2015-09-16 14:31:34
  • 1324

Android通过网络URL获取图片并显示

1.布局文件
  • esunshine1985
  • esunshine1985
  • 2017-03-18 17:10:17
  • 3133

Android异步加载网络图片

Android图片的异步加载,主要原理: 加载图片时先查看缓存中时候存在该图片,如果存在则返回该图片,否则先加载载一个默认的占位图片,同时创建一个通过网络获取图片的任务并添加,任务完成后放松消息给主...
  • geniusxiaoyu
  • geniusxiaoyu
  • 2012-04-17 16:30:17
  • 92442

Android网络图片加载三级缓存

一、概述网络图片的加载在Android的开发中是一个必不可少的功能,今天我们就来聊聊网络图片加载三级缓存策略。 所谓的三级缓存策略是指通过网络、本地、内存三级来缓存图片,减少不必要的网络交互,避免浪...
  • chenzheng8975
  • chenzheng8975
  • 2017-02-11 17:01:48
  • 950

android加载网络图片

最近在做一个加载网络图片的demo,之前的
  • he597080641
  • he597080641
  • 2014-04-23 15:44:15
  • 289

Android Volley完全解析(二),使用Volley加载网络图片

在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法。本篇文章中我们即将学习关于Volley更加高级的用法,如何你还没有看过我的上一篇文章的话,建议先去阅读Android Volley完...
  • sinyu890807
  • sinyu890807
  • 2014-04-17 09:23:22
  • 150365
    个人资料
    持之以恒
    等级:
    访问量: 8573
    积分: 278
    排名: 28万+
    最新评论