Android批量图片加载经典系列——使用xutil框架缓存、异步加载网络图片

一、问题描述

  为提高图片加载的效率,需要对图片的采用缓存和异步加载策略,编码相对比较复杂,实际上有一些优秀的框架提供了解决方案,比如近期在git上比较活跃的xutil框架

  Xutil框架提供了四大模块:

1、  DbUtil模块:采用ORM机制简化Sqlite操作,一行代码就可执行增删改查、支持事务、支持延迟策略

2、  ViewUtils模块:可以说是Android的IOC框架,可以注解方式对ui、资源、事件进行绑定

3、  HttpUtils模块:支持同步、异步请求、支持大文件上传

4、  BitmapUtils模块:图片的异步加载,支持本地和网络图片, 图片的压缩处理, 图片的内存缓存以及本地文件缓存。

  本案例主要使用Xutil的HttpUtils模块和BitmapUtils模块

二、案例介绍

  实现图片新闻浏览:

 Android批量图片加载经典系列——使用xutil框架缓存、异步加载网络图片

三、案例主要技术

1、使用HttpUtils模块实现网络通信

  (1)RequestParams组件设置请求参数、上传文件等信息

RequestParams params = new RequestParams(“utf-8”); // 默认编码UTF-8



params.addQueryStringParameter("categoryId","2");//设置参数

  (2) HttpUtils组件发送请求

HttpUtils http = new HttpUtils();



http.configResponseTextCharset("utf-8");// 设置返回文本的编码, 默认编码UTF-8



//发送请求,分别设置传送方式、url、传递数据、回调组件



httpUtils.send(HttpMethod.POST, "http://192.168.2.178:8080/21-sun/PhotosServlet", params,  new RequestCallBack<String>(){



                            @Override



                            public void onFailure(HttpException e, String m) {//执行失败回调方法



                                     Log.i("jereh", e.getExceptionCode()+" "+m);



                            }



                            @Overrid



                            public void onSuccess(ResponseInfo<String> info) {



                                     //执行成功回调方法,并传入数据,通过info.result获得返回数据



                            }       



                   });

2、使用BitmapUtils图片的异步加载

  使用BitmapUtils图片的异步加载,支持本地和网络图片, 图片的压缩处理。

  (1)、BitmapDisplayConfig图片显示的配置

   BitmapDisplayConfig  bigPicDisplayConfig = new BitmapDisplayConfig();

// 显示原始图片,不压缩, 尽量不要使用, 图片太大时容易OOM。

   bigPicDisplayConfig.setShowOriginal(true);        bigPicDisplayConfig.setBitmapConfig(Bitmap.Config.RGB_565);

//设置图片的最大尺寸, 不设置时更具控件属性自适应

displayConfig.setBitmapMaxSize(BitmapCommonUtils.getScreenSize(mActivity));

//实现一个渐变动画。

    AlphaAnimation animation=new AlphaAnimation(0.1f,1.0f);

    animation.setDuration(500);

    displayConfig.setAnimation(animation);

       (2) 创建BitmapUtils

  构造:

/**

* @param context 上下文 

     * @param diskCachePath  磁盘高速缓存路径 

     * @param memoryCacheSize 内存缓存大小

     * @param diskCacheSize 磁盘缓存空间大小

*/

BitmapUtils(Context  context, String  diskCachePath, 

int  memoryCacheSize, int  diskCacheSize)

  其他形式

BitmapUtils(Context context)

BitmapUtils(Context context, String  diskCachePath)

BitmapUtils(Context  context,  String diskCachePath, int  memoryCachePercent);

  代码:

// 获取应用程序最大可用内存

        int maxMemory = (int) Runtime.getRuntime().maxMemory();

        int cacheSize = maxMemory / 8;

        FileUtils fileUtils=new FileUtils(mActivity, "jereh");

        //设置文件缓存、内存缓存大小

        BitmapUtils  utils=new BitmapUtils(mActivity,fileUtils.getCacheDir(),cacheSize);

  (3)display()方法异步加载图片并显示到View控件上

utils.display(T  container , String  uri,   BitmapDisplayConfig   displayConfig);

3、Gson组件实现json数据的解析

Gson gson=new Gson();//创建gson组件

    //将服务器返回的JSON数据,使用Gson解析

List<ImageInfo> imageInfo=gson.fromJson(“JSON数据”, 

new TypeToken<ArrayList<ImageInfo>>(){}.getType());
四、案例完整代码

1、PhotoBrowseAdapter适配器代码

public class PhotoBrowseAdapter extends PagerAdapter {



    private Activity mActivity;

    private List<ImageInfo> imageList;

    private LayoutInflater inflate;

    private BitmapUtils utils;

    private BitmapDisplayConfig displayConfig;

    

    public PhotoBrowseAdapter(Activity mActivity, List<ImageInfo> imageList) {

        super();

        this.mActivity = mActivity;

        this.imageList = imageList;

        inflate=LayoutInflater.from(mActivity);

        // 获取应用程序最大可用内存

        int maxMemory = (int) Runtime.getRuntime().maxMemory();

        int cacheSize = maxMemory / 8;

        FileUtils fileUtils=new FileUtils(mActivity, "jereh");

        utils=new BitmapUtils(mActivity,fileUtils.getCacheDir(),cacheSize);

        displayConfig=new BitmapDisplayConfig();

        //displayConfig.setShowOriginal(true); // 显示原始图片,不压缩, 尽量不要使用, 图片太大时容易OOM。

    //utils.configDefaultBitmapMaxSize(BitmapCommonUtils.getScreenSize(mActivity));

        displayConfig.setBitmapMaxSize(BitmapCommonUtils.getScreenSize(mActivity));

        AlphaAnimation animation=new AlphaAnimation(0.1f,1.0f);

        animation.setDuration(500);

        displayConfig.setAnimation(animation);

    }



    @Override

    public int getCount() {

        // TODO Auto-generated method stub

        return imageList.size();

    }



    @Override

    public boolean isViewFromObject(View arg0, Object arg1) {

        // TODO Auto-generated method stub

        return arg0==arg1;

    }

    @Override

    public Object instantiateItem(View container,int position){

        ImageInfo info=imageList.get(position);

        LinearLayout view=(LinearLayout)inflate.inflate(R.layout.phone_item, null);

        ((TextView)view.findViewById(R.id.tvTitle)).setText(info.getImgTitle());

        ((TextView)view.findViewById(R.id.tvContent)).setText(info.getImgDesc());

        ImageView img=(ImageView)view.findViewById(R.id.ivPhoto);

        img.setTag(info.getImgUrl());

        utils.display(img,info.getImgUrl(),displayConfig);

        ((ViewPager)container).addView(view);

        return view;

    }

    @Override

    public void  destroyItem(View container,int position,Object obj){

        ((ViewPager)container).removeView((View)obj);

    }

    



}

2、MainActivity代码

    public class MainActivity extends Activity {

    private ViewPager vpImagePager;

    private PhotoBrowseAdapter adapter;

    private List<ImageInfo> imageInfoList;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        vpImagePager=(ViewPager)super.findViewById(R.id.vpImgBrowse);

        imageInfoList=new ArrayList<ImageInfo>();

        adapter=new PhotoBrowseAdapter(this,imageInfoList);

        loadData();

        

    } 

    

    private void loadData(){    

        RequestParams params=new RequestParams();

        params.addQueryStringParameter("categoryId","2");//设置参数

        HttpUtils httpUtils=new HttpUtils();

        //向服务器发送请求

httpUtils.send(HttpMethod.POST, "http://192.168.2.178:8080/21-sun/PhotosServlet",

         params,new RequestCallBack<String>(){

            @Override

            public void onFailure(HttpException e, String m) {

                Log.i("jereh", e.getExceptionCode()+" "+m);

            }

            @Override

            public void onSuccess(ResponseInfo<String> info) {//后台执行完成后回调,并传入返回数据

                Gson gson=new Gson();//创建gson组件

                //将info.result服务器返回的JSON数据,使用Gson解析

                List<ImageInfo> imageInfo=gson.fromJson(info.result,

 new TypeToken<ArrayList<ImageInfo>>(){}.getType());

                imageInfoList.addAll(imageInfo);

                vpImagePager.setAdapter(adapter);

            }    

        });

    }

}

3、ImageInfo实体类和 FileUtils工具类

//封装图片信息

public class ImageInfo {

    private String imgUrl;

    private String imgTitle;

    private String imgDesc;

    …//省略

}

FileUtils获得文件缓存目录

public class FileUtils {

    /** 缓存文件目录 */

    private File mCacheDir; 

    public FileUtils(Context context, String cacheDir){

    if (android.os.Environment.getExternalStorageState().

equals(android.os.Environment.MEDIA_MOUNTED))

         mCacheDir = new File(cacheDir);

      else

         mCacheDir = context.getCacheDir();// 如何获取系统内置的缓存存储路径

      if(!mCacheDir.exists())

            mCacheDir.mkdirs();

    } 

    public String getCacheDir(){

            return mCacheDir.getAbsolutePath();

    }

4、服务端PhotosServlet代码

public void doPost (HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

    response.setContentType("text/json;charset=utf-8");

    String categoryId=request.getParameter("categoryId");//测试传递参数

    System.out.println(categoryId);

    List<ImagePart> partList=new ArrayList<ImagePart>();

    ImagePart part1=new ImagePart();                part1.setImgUrl("http://news.21-sun.com/UserFiles/x_Image/x_20150216131001_0.jpg");

    part1.setImgTitle("代表中国的东风队,加油!");

    part1.setImgDesc("...");

    ImagePart part2=new ImagePart();

    part2.setImgUrl("http://news.21-sun.com/UserFiles/x_Image/x_20150216131432_0.jpg");

        part2.setImgTitle("三亚沃帆赛体验之旅");

        part2.setImgDesc("...");

        ImagePart part3=new ImagePart();

        part3.setImgUrl("http://news.21-sun.com/UserFiles/x_Image/x_20150216131157_0.jpg");

        part3.setImgTitle("沃尔沃集团总裁兼首席执行官欧罗夫•佩森与沃尔沃");

        part3.setImgDesc("...");

        partList.add(part1);partList.add(part2);partList.add(part3);

        JSONArray jsonArray=JSONArray.fromObject(partList,config);

        response.getWriter().println(jsonArray.toString());

    }

 

  想要了解更多内容的小伙伴,可以点击查看源码,亲自运行测试。

  疑问咨询或技术交流,请加入官方QQ群:JRedu技术交流 (452379712)

 

作者: 杰瑞教育
出处: http://www.cnblogs.com/jerehedu/ 
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

你可能感兴趣的:(android)