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/ 
本文版權歸煙台傑瑞教育科技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM