国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

分享一個(gè)輕量級圖片加載類 ImageLoader

2019-12-12 05:40:40
字體:
供稿:網(wǎng)友

ImageLoader 這類的 圖片加載網(wǎng)絡(luò)上一大推,像比較出名的有nostra13 的-Image-Loader圖片加載,xUtil的圖片加載,還有 Facebook 的 Fresco 。很多,但本著求學(xué)的態(tài)度,最近在做項(xiàng)目時(shí)有圖片加載這個(gè)需求就自己寫了個(gè)輕量級的 (本地)圖片緩存加載 功能,分享給各位。

里面涉及了 LruCache ,ExecutorService,處理大圖的 BitmapFactory 原理,view.setTag() .

好了,不多說,先一步一步來:
首先看一下我封裝的類怎么使用:

    // 本地照片絕對路徑    String imageUrl = (String) t;    // 得到 ImageView     ImageView grid_item = holder.getView(R.id.grid_item);    // 設(shè)置 tag ,標(biāo)記用的,反正圖片顯示錯(cuò)位    grid_item.setTag(imageUrl);         /**     * 顯示 圖片     *      * @param context     *      : 上下文     * @param imageView     *      : ImageView 控件     * @param sourcePath     *      : 圖片 地址     * @param r_Id     *      : 默認(rèn) 圖片 id ,R.drowable.id;     * @param callback     *      :圖片顯示 回調(diào)     */     new ImageLoader().displayBmp(mContext,grid_item, imageUrl, R.drawable.img_bg,this); 

是不是很簡單。

接下來具體分析 ImageLoader 這個(gè)類:

都知道手機(jī)的內(nèi)存有限,不可能將所有的圖片都加進(jìn)內(nèi)存,所以android 提供了一個(gè) LruCache 方法,用到的 算法 是 :近期最少使用算法 ,及在圖片不斷的加進(jìn)緩存,最少使用的圖片也在不斷的移除緩存 ,從而避免的內(nèi)存不夠的問題。

LruCache 的初始化代碼如下:

  public ImageLoader() {    // 取應(yīng)用內(nèi)存的 8/1 作為 圖片緩存用    int cacheSize = maxMemory / 8;    // 得到 LruCache    mLruCache = new LruCache<String, Bitmap>(cacheSize) {      @Override      protected int sizeOf(String key, Bitmap bitmap) {        return bitmap.getByteCount();      }    };  }  /**   * 將圖片存儲到LruCache   */  public void putBitmapToLruCache(String key, Bitmap bitmap) {    if (getBitmapFromLruCache(key) == null && mLruCache != null) {      mLruCache.put(key, bitmap);    }  }  /**   * 從LruCache緩存獲取圖片   */  public Bitmap getBitmapFromLruCache(String key) {    return mLruCache.get(key);  }

LruCache 就像 HashMap 一樣 利用put 和 get 得到緩存的東西。

接著看 圖片的 具體加載,先把代碼貼出來:

  /**   * 顯示 圖片   *    * @param context   *      : 上下文   * @param imageView   *      : ImageView 控件   * @param sourcePath   *      : 圖片 地址   * @param r_Id   *      : 默認(rèn) 圖片 id ,R.drowable.id;   * @param callback   *      :圖片顯示 回調(diào)   */  public void displayBmp(final Context context, final ImageView imageView, final String sourcePath, final int r_Id,      final ImageCallback callback) {    final String path;    if (!TextUtils.isEmpty(sourcePath)) {      path = sourcePath;    } else {      return;    }    // 先 試著 從 緩存 得到 圖片 , path 作為 圖片的 key    Bitmap bmp = mLruCache.get(path);    if (bmp != null) {      if (callback != null) {        // 回調(diào) 圖片 顯示        callback.imageLoad(imageView, bmp, sourcePath);      }      // imageView.setImageBitmap(bmp);      return;    }    // 如果 bmp == null ,給 imageView 顯示默認(rèn)圖片    imageView.setImageResource(r_Id);    // 啟動(dòng) 線程池    threadPoolUtils.getExecutorService().execute(new Runnable() {      Bitmap bitmap = null;      @Override      public void run() {        // TODO Auto-generated method stub        try {          // 加載 圖片 地址 對應(yīng) 的 縮略圖          bitmap = revitionImageSize(imageView, sourcePath);        } catch (Exception e) {        }        if (bitmap == null) {          try {            // 如果 縮略圖 沒加載成功 顯示 默認(rèn) 設(shè)置的圖片            bitmap = BitmapFactory.decodeResource(context.getResources(), r_Id);          } catch (Exception e) {          }        }        if (path != null && bitmap != null) {          // 將 縮略圖 放進(jìn) 緩存 , path 作為 key          putBitmapToLruCache(path, bitmap);        }        if (callback != null) {          handler.post(new Runnable() {            @Override            public void run() {              // 回調(diào) 圖片 顯示              callback.imageLoad(imageView, bitmap, sourcePath);            }          });        }      }    });  }

代碼不是狠多,主要就是 先從緩存加載圖片,當(dāng)加載圖片為空時(shí),再從手機(jī)的圖片地址加載圖片

bitmap = revitionImageSize(imageView, sourcePath);

加載緩存圖片就不多說了,看的也明白, mLruCache.get(key);就這么簡單

具體分析 revitionImageSize() 這個(gè)方法吧:

  public Bitmap revitionImageSize(ImageView imageView, String path) throws IOException {    // 得到 布局 ImageView 的 寬高    int img_width = imageView.getWidth();    int img_height = imageView.getHeight();     BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(path)));    BitmapFactory.Options options = new BitmapFactory.Options();    options.inJustDecodeBounds = true;    BitmapFactory.decodeStream(in, null, options);    in.close();    int height = options.outHeight;    int width = options.outWidth;    Bitmap bitmap = null;     int inSampleSize = 1;    // 計(jì)算出實(shí)際寬高和目標(biāo)寬高的比率    final int heightRatio = Math.round((float) height / (float) img_height);    final int widthRatio = Math.round((float) width / (float) img_width);    // 選擇寬和高中最小的比率作為inSampleSize的值,這樣可以保證最終圖片的寬和高    // 一定都會(huì)大于等于目標(biāo)的寬和高。    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;    // 調(diào)用上面定義的方法計(jì)算inSampleSize值    options.inSampleSize = inSampleSize;    options.inJustDecodeBounds = false;    in = new BufferedInputStream(new FileInputStream(new File(path)));    bitmap = BitmapFactory.decodeStream(in, null, options);    in.close();    return bitmap;  }

代碼我也寫了注釋了 ,一般在加載圖片時(shí)都有對圖片一定的壓縮處理避免OOM,所以上面的處理方法也是挺常見的,對要顯示 圖片 根據(jù) imageview 控件大小進(jìn)行一定的壓縮。

如果對 圖片壓縮處理不是很理解的朋友這么我簡單解釋一下:

首先加載完圖片:

BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(path)));

然后:

options.inJustDecodeBounds = true;

再接著:

int height = options.outHeight;int width = options.outWidth;

這時(shí)候注意 程序并沒有把圖片真正的加載進(jìn)來,options.inJustDecodeBounds = true;

這句在起作用,但圖片的寬和高 的信息我們卻得到了,就可以處理壓縮圖片了!

壓縮完圖片再:

options.inJustDecodeBounds = false;

重新得到壓縮后的圖片:

bitmap = BitmapFactory.decodeStream(in, null, options);

解釋完畢。

仔細(xì)看代碼的同學(xué)會(huì)發(fā)現(xiàn) displayBmp() 方法里面有個(gè) 回調(diào)參數(shù):

回調(diào)接口如下:

  /**   * 顯示圖片回調(diào)   *    * @author Administrator   *   */  public interface ImageCallback {    public void imageLoad(ImageView imageView, Bitmap bitmap, Object... params);  }

具體實(shí)現(xiàn)是在顯示圖片的地方回調(diào)的:

   /**   * 圖片 緩存回調(diào)   */  @Override  public void imageLoad(ImageView imageView, Bitmap bitmap, Object... params) {    if (imageView != null && bitmap != null) {      String url = (String) params[0];      // 判斷 這里的 url 是否 對應(yīng) imageView.getTag()      // 如果 將這句 判斷 去掉 那么 就會(huì)出現(xiàn) 經(jīng)常出現(xiàn)的 圖片 顯示 錯(cuò)位 問題 !!!!      if (url != null && url.equals((String) imageView.getTag())) {        ((ImageView) imageView).setImageBitmap(bitmap);      }    }  }

代碼注釋的地方也寫了,不太理解的同學(xué)可以私信交流,另外附上我 github github連接上的源碼,可以下載下了運(yùn)行方便好理解:

為了你方便使用,在你的項(xiàng)目中添加如下依賴即可:

dependencies {      compile 'com.zts:imageloader:1.1.1'  }

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 无极县| 健康| 深水埗区| 乌鲁木齐市| 长汀县| 英吉沙县| 普陀区| 勐海县| 乌兰察布市| 昭觉县| 应城市| 华亭县| 长沙市| 双鸭山市| 江源县| 罗甸县| 罗源县| 嵊州市| 兴安县| 左权县| 得荣县| 建宁县| 望谟县| 元氏县| 兰坪| 淳化县| 大悟县| 贵溪市| 什邡市| 和顺县| 射阳县| 当阳市| 永平县| 当涂县| 丰原市| 阿拉尔市| 东至县| 崇礼县| 云霄县| 隆德县| 邵东县|