簡單實現本身的相似UniversalImageLoader網絡圖片加載緩存框架

前言

一直以來都在用第三方框架加載圖片,由於這樣會省下很多的開發成本,經常使用的一些如universal-image-loader以及谷歌官方的圖片框架glide或者類似的picasso都基本上可以知足咱們開發的需求。
本着學習的態度,在參考了若干案例以後,站着擼了一個相似universal-image-loader的框架,怎麼評價它呢,一句話:湊合湊合能用吧~
已併入我本身寫的小工具AnnUtils的imageloader模塊,傳送門:githubjava

原理

圖片加載緩存,工做原理:根據相關url加載圖片時,第一先從內存緩存中查找是否有該圖片的緩存,而後從文件緩存中查找是否有緩存,最後從指定的url中下載圖片。git

主要代碼

主要方法:github

public void displayImage(String url, ImageView imageView, int requiredSize, OnImageLoaderListener listener) {
        imageViews.put(imageView, url);
        // 先從內存緩存中查找
        Bitmap bitmap = memoryCache.get(url);
        if (bitmap != null){
            imageView.setImageBitmap(bitmap);
            if(null != listener){
                listener.onFinishedImageLoader(imageView, bitmap); // 通知完成加載
            }
        } else {
            // 若沒有的話則設置成默認圖片,並開啓新線程加載真實須要的圖片
            imageView.setImageResource(config.getDefaultResId());
            loadPhoto(url, imageView, requiredSize, listener);
        }
    }

加載網絡圖片以及回調進度參數的方法緩存

/**
     * 執行網絡請求加載圖片
     * @param url
     * @param requiredSize
     * @return
     */
    private Bitmap getBitmap(String url, int requiredSize, PhotoToLoad photoToLoad) {
        File f = fileCache.getFile(url);
        // 先從文件緩存中查找是否有
        Bitmap b = decodeFile(f, requiredSize);
        if (b != null)
            return b;

        // 最後從指定的url中下載圖片
        try {
            Bitmap bitmap = null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl
                    .openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
//            CopyStream(is, os, conn.getContentLength(), photoToLoad);

            photoToLoad.totalSize = conn.getContentLength();
            int buffer_size = 1024;
            byte[] bytes = new byte[buffer_size];
            for (; ; ) {
                int count = is.read(bytes, 0, buffer_size);

                if (count == -1){
                    break;
                }
                os.write(bytes, 0, count);

                if(null != photoToLoad.onImageLoaderListener){ // 若是設置了圖片加載監聽,則回調
                    Message msg = handler.obtainMessage();
                    photoToLoad.currentSize += count;
                    msg.arg1 = IMAGE_LOADER_PROCESS;
                    msg.obj = photoToLoad;
                    handler.sendMessage(msg);
                }

            }

            is.close();
            os.close();
            bitmap = decodeFile(f, requiredSize);
            return bitmap;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

具體實現能夠參考源碼網絡

使用方式

配置初始化

AnnImageLoader.init(getApplicationContext(),
     new CacheConfig()
     .setDefRequiredSize(600) // 設置默認的加載圖片尺寸(表示寬高任一不超過該值,默認是70px)
     .setDefaultResId(R.drawable.ic_launcher) // 設置顯示的默認圖片(默認是0,即空白圖片)
     .setBitmapConfig(Bitmap.Config.ARGB_8888) // 設置圖片位圖模式(默認是Bitmap.CacheConfig.ARGB_8888)
     .setMemoryCachelimit(Runtime.getRuntime().maxMemory() / 3) // 設置圖片內存緩存大小(默認是Runtime.getRuntime().maxMemory() / 4)
     .setFileCachePath(Environment.getExternalStorageDirectory().toString() + "/mycache") // 設置文件緩存保存目錄
 );

顯示圖片

AnnImageLoader.getInstances().displayImage(url,imageview, new AnnImageLoader.OnImageLoaderListener() {
            @Override
            public void onProgressImageLoader(ImageView imageView, int currentSize, int totalSize) {
                //進度條
            }

            @Override
            public void onFinishedImageLoader(ImageView imageView, Bitmap bitmap) {
                //加載結束
            }
        });

總結

實現的方式很簡單,有網絡,有自定義控件,有涉及內存的使用,雖然還有不少的不足,可是從中總結到了許多本身日常須要用到的知識,就看成是本身的一個鍛鍊吧。框架

相關文章
相關標籤/搜索