Volley+Cache 实现GridWall图片加载

Posted xiaoleiacm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Volley+Cache 实现GridWall图片加载相关的知识,希望对你有一定的参考价值。

当前主流的APP已放弃了图片的三级缓存,直接使用“网络缓存+内存缓存”减少空间浪费,加快程序运行效率,这种方式的组合很适合使用Volley的NetworkImageView + LruCache的方式。即用Volley实现网络缓存 ,用LruCache 实现内存缓存。

由于是在GridView或者ListView中,所以代码实现在适配中最为方便。

1 布局

GridView布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
 >
    <GridView
        android:id="@+id/gv_Content"
        android:numColumns="3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchMode="columnWidth"
        android:gravity="center"/>


</LinearLayout>


NetworkImageView 的XML文件布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.android.volley.toolbox.NetworkImageView

        android:layout_gravity="center"
        android:id="@+id/iv_ItemContent"
        android:layout_width="90dp"
        android:layout_height="90dp" 
        android:src="@mipmap/ic_launcher"/>
</LinearLayout>


2 初始化:

网络缓存,内存缓存初始化:

private ImageLoader imageLoader;
private void InitNetCache_MemeroyCache() 

        // volley 网络添加新的图片

        /*************************************************************
         * 内存缓存初始化 开始
         ***********************************************************/
        // 为程序添加图片缓存,并设置缓存大小
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory / 8;

        final LruCache<String, Bitmap> mMemoryCache = new LruCache<String, Bitmap>(cacheSize) 
            @Override
            protected int sizeOf(String key, Bitmap value) 
                System.out.println(".................................sizeOf :" + value.getByteCount());
                return value.getByteCount(); // 获取图片大小

            
        ;

        /**
         * 每一次setImageUrl时加载新图片都会先执行getBitmap,看在缓存中是否存在,如果不存在,则执行putmap获取bitmap对象
         */
        ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() 
            @Override
            public void putBitmap(String url, Bitmap bitmap) 
                System.out.println("imageCache : putBitmap()");

                mMemoryCache.put(url, bitmap);
            

            @Override
            public Bitmap getBitmap(String url) 
                System.out.println("imageCache : getBitmap()");
                return mMemoryCache.get(url);
            
        ;
        /*************************************************************
         *  内存缓存初始化 结束
         ***********************************************************/


        /****************************************************
         * 网络缓存初始化 开始
         ***************************************************/
        RequestQueue requestQueue = Volley.newRequestQueue(mContext);
        imageLoader = new ImageLoader(requestQueue, imageCache);

        /**************************************************
         * 网络缓存初始化 结束
         **************************************************/

    

3 应用

由于NetworkImageView加载图片使用url作为区分不同图片的参数,直接传入URL即可。

在getView函数中为Networkimageview 设置网络图片:

private void setImageView(String imageUrl, NetworkImageView imageView) 

        imageView.setImageUrl(imageUrl, imageLoader);
    

NOTE:

这样就很简单的实现了网络缓存以及内存缓存的功能,由于Volley已经完全实现了HttpURLConnection 以及HttpClient,所以不需要对底层进一步封装,也不需要对应用层HTTP协议进行包拼接,OKHttp在Android4.4中也被应用到Volley,非常方便使用。

在另一篇博客中使用了三级缓存,对于需要本地缓存的应用场景,可使用HttpUrlConnection,相对方便控制加载过程。http://blog.csdn.net/xiaoleiacmer/article/details/50482863


与Volley相关的两旁给力博客:

http://blog.csdn.net/guolin_blog/article/details/17482095

http://blog.csdn.net/guolin_blog/article/details/17482165


本例代码:http://download.csdn.net/detail/xiaoleiacm/9510951

package com.example.admin.gridviewwall.Adapter;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.GridView;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;
import com.example.admin.gridviewwall.R;

/**
 * Created by admin on 2016/5/4.
 */
public class PhotoWallAdapter4 extends ArrayAdapter<String> implements AbsListView.OnScrollListener 
    private GridView mPhotoWall;
    private Context mContext;

    private ImageLoader imageLoader;


    private int mfirstVisbleItem;
    private int mvisibleItemCount;

    public PhotoWallAdapter4(Context context, int resource) 
        super(context, resource);
    

    public PhotoWallAdapter4(Context context, int resource, int textViewResourceId, String[] objects, GridView gridview) 
        super(context, resource, textViewResourceId, objects);


        mContext = getContext();
        mPhotoWall = gridview;
        mPhotoWall.setOnScrollListener(this);


        InitNetCache_MemeroyCache();
    


    private void InitNetCache_MemeroyCache() 

        // volley 网络添加新的图片

        /*************************************************************
         * 内存缓存初始化 开始
         ***********************************************************/
        // 为程序添加图片缓存,并设置缓存大小
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory / 8;

        final LruCache<String, Bitmap> mMemoryCache = new LruCache<String, Bitmap>(cacheSize) 
            @Override
            protected int sizeOf(String key, Bitmap value) 
                System.out.println(".................................sizeOf :" + value.getByteCount());
                return value.getByteCount(); // 获取图片大小

            
        ;

        /**
         * 每一次setImageUrl时加载新图片都会先执行getBitmap,看在缓存中是否存在,如果不存在,则执行putmap获取bitmap对象
         */
        ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() 
            @Override
            public void putBitmap(String url, Bitmap bitmap) 
                System.out.println("imageCache : putBitmap()");

                mMemoryCache.put(url, bitmap);
            

            @Override
            public Bitmap getBitmap(String url) 
                System.out.println("imageCache : getBitmap()");
                return mMemoryCache.get(url);
            
        ;
        /*************************************************************
         *  内存缓存初始化 结束
         ***********************************************************/


        /****************************************************
         * 网络缓存初始化 开始
         ***************************************************/
        RequestQueue requestQueue = Volley.newRequestQueue(mContext);
        imageLoader = new ImageLoader(requestQueue, imageCache);

        /**************************************************
         * 网络缓存初始化 结束
         **************************************************/

    



    /*****************
     * GridView 开始
     ****************************************************************/
    @Override
    public View getView(int position, View convertView, ViewGroup parent) 

        String imageUrl = getItem(position);
//        System.out.println("Url : " + imageUrl);
        View view;
        if (convertView == null) 
            view = LayoutInflater.from(getContext()).inflate(R.layout.item_gridview, null);
         else 
            view = convertView;
        


        //使用Volley下载网络图片
        NetworkImageView photo = (NetworkImageView) view.findViewById(R.id.iv_ItemContent);
        photo.setTag(imageUrl);
        setImageView(imageUrl, photo);

        return view;
    

    private void setImageView(String imageUrl, NetworkImageView imageView) 

        imageView.setImageUrl(imageUrl, imageLoader);
    

    /*****************
     * GridView 结束
     ****************************************************************/


//


    /***********************
     * 滚动状态指示 开始
     * ************************************************************************/

    /**
     * 滚动状态指示函数
     *
     * @param view
     * @param scrollState
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) 


//        for (int i = mfirstVisbleItem; i < mfirstVisbleItem + mvisibleItemCount; i++) 
//            String url = getItem(i);
//            NetworkImageView networkimageviewbytag = (NetworkImageView) mPhotoWall.findViewWithTag(url);
//
//            networkimageviewbytag.setImageUrl(url, imageLoader);
//
//        
    

    /**
     * 滚动指示函数
     *
     * @param view
     * @param firstVisibleItem
     * @param visibleItemCount
     * @param totalItemCount
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) 

        mfirstVisbleItem = firstVisibleItem;
        mvisibleItemCount = visibleItemCount;

//        for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) 
//            String url = getItem(i);
//            NetworkImageView networkimageviewbytag = (NetworkImageView) mPhotoWall.findViewWithTag(url);
//
//            networkimageviewbytag.setImageUrl(url, imageLoader);
//
//        
    


    /*************************
     * 滚动状态指示 结束
     **********************************************************************/







以上是关于Volley+Cache 实现GridWall图片加载的主要内容,如果未能解决你的问题,请参考以下文章

Volley框架载入网络图片

android-----Volley框架使用ImageLoader加载图片源码分析

Androiid_Volley+Image-Loader+RecyclerView实现网络下载图片瀑布流

Android_Volley+Image-Loader+RecyclerView实现网络下载图片瀑布流

Android_Volley+Image-Loader+RecyclerView实现网络下载图片瀑布流

Volley HTTP 缓存机制