zoukankan      html  css  js  c++  java
  • Android批量图片加载经典系列——使用xutil框架缓存、异步加载网络图片

    一、问题描述

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

      Xutil框架提供了四大模块:

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

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

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

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

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

    二、案例介绍

      实现图片新闻浏览:

     

    三、案例主要技术

    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/ 
    本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
     
  • 相关阅读:
    无线路由器的工作模式
    php 利用root 权限执行shell脚本
    shell 终端常用插件
    linux space/mark设置
    推送唯一标识符
    微信支付跨平台软件架构
    celery 动态配置定时任务
    两个报文是如何进行 TCP 分组传输
    接口 Interfaces
    How does Circus stack compare to a classical stack?
  • 原文地址:https://www.cnblogs.com/jerehedu/p/4576865.html
Copyright © 2011-2022 走看看