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

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

Android編程圖片加載類ImageLoader定義與用法實(shí)例分析

2019-10-22 18:20:50
字體:
供稿:網(wǎng)友

本文實(shí)例講述了Android編程圖片加載類ImageLoader定義與用法。分享給大家供大家參考,具體如下:

解析:

1)圖片加載使用單例模式,避免多次調(diào)用時(shí)產(chǎn)生死鎖
2)核心對(duì)象 LruCache

圖片加載時(shí)先判斷緩存里是否有圖片,如果有,就使用緩存里的

沒有就加載網(wǎng)絡(luò)的,然后置入緩存

3)使用了線程池ExecutorService mThreadPool技術(shù)
4)使用了Semaphore 信號(hào)來控制變量按照先后順序執(zhí)行,避免空指針的問題

如何使用:

在Adapter里加載圖片時(shí)

復(fù)制代碼 代碼如下:
ImageLoader.getInstance.loadImage("http://www.baidu.com/images/kk.jpg", mImageView, true);

 

源碼:

/** * @描述 圖片加載類 * @項(xiàng)目名稱 App_News * @包名 com.android.news.tools * @類名 ImageLoader * @author chenlin * @date 2015-3-7 下午7:35:28 * @version 1.0 */public class ImageLoader {  private static ImageLoader mInstance;  /**   * 圖片緩存的核心對(duì)象   */  private LruCache<String, Bitmap> mLruCache;  /**   * 線程池   */  private ExecutorService mThreadPool;  private static final int DEAFULT_THREAD_COUNT = 1;  /**   * 隊(duì)列的調(diào)度方式   */  private Type mType = Type.LIFO;  /**   * 任務(wù)隊(duì)列   */  private LinkedList<Runnable> mTaskQueue;  /**   * 后臺(tái)輪詢線程   */  private Thread mPoolThread;  private Handler mPoolThreadHandler;  /**   * UI線程中的Handler   */  private Handler mUIHandler;  private Semaphore mSemaphorePoolThreadHandler = new Semaphore(0);  private Semaphore mSemaphoreThreadPool;  private boolean isDiskCacheEnable = true;  private static final String TAG = "ImageLoader";  public enum Type {    FIFO, LIFO;  }  private ImageLoader(int threadCount, Type type) {    init(threadCount, type);  }  /**   * 初始化   *   * @param threadCount   * @param type   */  private void init(int threadCount, Type type) {    initBackThread();    // 獲取我們應(yīng)用的最大可用內(nèi)存    int maxMemory = (int) Runtime.getRuntime().maxMemory();    int cacheMemory = maxMemory / 8;    mLruCache = new LruCache<String, Bitmap>(cacheMemory) {      @Override      protected int sizeOf(String key, Bitmap value) {        return value.getRowBytes() * value.getHeight();      }    };    // 創(chuàng)建線程池    mThreadPool = Executors.newFixedThreadPool(threadCount);    mTaskQueue = new LinkedList<Runnable>();    mType = type;    mSemaphoreThreadPool = new Semaphore(threadCount);  }  /**   * 初始化后臺(tái)輪詢線程   */  private void initBackThread() {    // 后臺(tái)輪詢線程    mPoolThread = new Thread() {      @Override      public void run() {        Looper.prepare();        mPoolThreadHandler = new Handler() {          @Override          public void handleMessage(Message msg) {            // 線程池去取出一個(gè)任務(wù)進(jìn)行執(zhí)行            mThreadPool.execute(getTask());            try {              mSemaphoreThreadPool.acquire();            } catch (InterruptedException e) {            }          }        };        // 釋放一個(gè)信號(hào)量        mSemaphorePoolThreadHandler.release();        Looper.loop();      };    };    mPoolThread.start();  }  public static ImageLoader getInstance() {    if (mInstance == null) {      synchronized (ImageLoader.class) {        if (mInstance == null) {          mInstance = new ImageLoader(DEAFULT_THREAD_COUNT, Type.LIFO);        }      }    }    return mInstance;  }  public static ImageLoader getInstance(int threadCount, Type type) {    if (mInstance == null) {      synchronized (ImageLoader.class) {        if (mInstance == null) {          mInstance = new ImageLoader(threadCount, type);        }      }    }    return mInstance;  }  /**   * 根據(jù)path為imageview設(shè)置圖片   *   * @param path   * @param imageView   */  public void loadImage(final String path, final ImageView imageView, final boolean isFromNet) {    imageView.setTag(path);    if (mUIHandler == null) {      mUIHandler = new Handler() {        public void handleMessage(Message msg) {          // 獲取得到圖片,為imageview回調(diào)設(shè)置圖片          ImgBeanHolder holder = (ImgBeanHolder) msg.obj;          Bitmap bm = holder.bitmap;          ImageView imageview = holder.imageView;          String path = holder.path;          // 將path與getTag存儲(chǔ)路徑進(jìn)行比較          if (imageview.getTag().toString().equals(path)) {            imageview.setImageBitmap(bm);          }        };      };    }    // 根據(jù)path在緩存中獲取bitmap    Bitmap bm = getBitmapFromLruCache(path);    if (bm != null) {      refreashBitmap(path, imageView, bm);    } else {      addTask(buildTask(path, imageView, isFromNet));    }  }  /**   * 根據(jù)傳入的參數(shù),新建一個(gè)任務(wù)   *   * @param path   * @param imageView   * @param isFromNet   * @return   */  private Runnable buildTask(final String path, final ImageView imageView, final boolean isFromNet) {    return new Runnable() {      @Override      public void run() {        Bitmap bm = null;        if (isFromNet) {          File file = getDiskCacheDir(imageView.getContext(), md5(path));          if (file.exists())// 如果在緩存文件中發(fā)現(xiàn)          {            Log.e(TAG, "find image :" + path + " in disk cache .");            bm = loadImageFromLocal(file.getAbsolutePath(), imageView);          } else {            if (isDiskCacheEnable)// 檢測(cè)是否開啟硬盤緩存            {              boolean downloadState = DownloadImgUtils.downloadImgByUrl(path, file);              if (downloadState)// 如果下載成功              {                Log.e(TAG,                    "download image :" + path + " to disk cache . path is "                        + file.getAbsolutePath());                bm = loadImageFromLocal(file.getAbsolutePath(), imageView);              }            } else            // 直接從網(wǎng)絡(luò)加載            {              Log.e(TAG, "load image :" + path + " to memory.");              bm = DownloadImgUtils.downloadImgByUrl(path, imageView);            }          }        } else {          bm = loadImageFromLocal(path, imageView);        }        // 3、把圖片加入到緩存        addBitmapToLruCache(path, bm);        refreashBitmap(path, imageView, bm);        mSemaphoreThreadPool.release();      }    };  }  private Bitmap loadImageFromLocal(final String path, final ImageView imageView) {    Bitmap bm;    // 加載圖片    // 圖片的壓縮    // 1、獲得圖片需要顯示的大小    ImageSize imageSize = ImageSizeUtil.getImageViewSize(imageView);    // 2、壓縮圖片    bm = decodeSampledBitmapFromPath(path, imageSize.width, imageSize.height);    return bm;  }  /**   * 從任務(wù)隊(duì)列取出一個(gè)方法   *   * @return   */  private Runnable getTask() {    if (mType == Type.FIFO) {      return mTaskQueue.removeFirst();    } else if (mType == Type.LIFO) {      return mTaskQueue.removeLast();    }    return null;  }  /**   * 利用簽名輔助類,將字符串字節(jié)數(shù)組   *   * @param str   * @return   */  public String md5(String str) {    byte[] digest = null;    try {      MessageDigest md = MessageDigest.getInstance("md5");      digest = md.digest(str.getBytes());      return bytes2hex02(digest);    } catch (NoSuchAlgorithmException e) {      e.printStackTrace();    }    return null;  }  /**   * 方式二   *   * @param bytes   * @return   */  public String bytes2hex02(byte[] bytes) {    StringBuilder sb = new StringBuilder();    String tmp = null;    for (byte b : bytes) {      // 將每個(gè)字節(jié)與0xFF進(jìn)行與運(yùn)算,然后轉(zhuǎn)化為10進(jìn)制,然后借助于Integer再轉(zhuǎn)化為16進(jìn)制      tmp = Integer.toHexString(0xFF & b);      if (tmp.length() == 1)// 每個(gè)字節(jié)8為,轉(zhuǎn)為16進(jìn)制標(biāo)志,2個(gè)16進(jìn)制位      {        tmp = "0" + tmp;      }      sb.append(tmp);    }    return sb.toString();  }  private void refreashBitmap(final String path, final ImageView imageView, Bitmap bm) {    Message message = Message.obtain();    ImgBeanHolder holder = new ImgBeanHolder();    holder.bitmap = bm;    holder.path = path;    holder.imageView = imageView;    message.obj = holder;    mUIHandler.sendMessage(message);  }  /**   * 將圖片加入LruCache   *   * @param path   * @param bm   */  protected void addBitmapToLruCache(String path, Bitmap bm) {    if (getBitmapFromLruCache(path) == null) {      if (bm != null)        mLruCache.put(path, bm);    }  }  /**   * 根據(jù)圖片需要顯示的寬和高對(duì)圖片進(jìn)行壓縮   *   * @param path   * @param width   * @param height   * @return   */  protected Bitmap decodeSampledBitmapFromPath(String path, int width, int height) {    // 獲得圖片的寬和高,并不把圖片加載到內(nèi)存中    BitmapFactory.Options options = new BitmapFactory.Options();    options.inJustDecodeBounds = true;    BitmapFactory.decodeFile(path, options);    options.inSampleSize = ImageSizeUtil.caculateInSampleSize(options, width, height);    // 使用獲得到的InSampleSize再次解析圖片    options.inJustDecodeBounds = false;    Bitmap bitmap = BitmapFactory.decodeFile(path, options);    return bitmap;  }  private synchronized void addTask(Runnable runnable) {    mTaskQueue.add(runnable);    // if(mPoolThreadHandler==null)wait();    try {      if (mPoolThreadHandler == null)        mSemaphorePoolThreadHandler.acquire();    } catch (InterruptedException e) {    }    mPoolThreadHandler.sendEmptyMessage(0x110);  }  /**   * 獲得緩存圖片的地址   *   * @param context   * @param uniqueName   * @return   */  public File getDiskCacheDir(Context context, String uniqueName) {    String cachePath;    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {      cachePath = context.getExternalCacheDir().getPath();    } else {      cachePath = context.getCacheDir().getPath();    }    return new File(cachePath + File.separator + uniqueName);  }  /**   * 根據(jù)path在緩存中獲取bitmap   *   * @param key   * @return   */  private Bitmap getBitmapFromLruCache(String key) {    return mLruCache.get(key);  }  private class ImgBeanHolder {    Bitmap bitmap;    ImageView imageView;    String path;  }}

相關(guān)工具類:

/** * @描述 獲取圖片大小工具類s * @項(xiàng)目名稱 App_News * @包名 com.android.news.util * @類名 ImageSizeUtil * @author chenlin * @date 2014-3-7 下午7:37:50 * @version 1.0 */public class ImageSizeUtil {  /**   * 根據(jù)需求的寬和高以及圖片實(shí)際的寬和高計(jì)算SampleSize   *   * @param options   * @param width   * @param height   * @return   */  public static int caculateInSampleSize(Options options, int reqWidth, int reqHeight) {    int width = options.outWidth;    int height = options.outHeight;    int inSampleSize = 1;    if (width > reqWidth || height > reqHeight) {      int widthRadio = Math.round(width * 1.0f / reqWidth);      int heightRadio = Math.round(height * 1.0f / reqHeight);      inSampleSize = Math.max(widthRadio, heightRadio);    }    return inSampleSize;  }  /**   * 根據(jù)ImageView獲適當(dāng)?shù)膲嚎s的寬和高   *   * @param imageView   * @return   */  public static ImageSize getImageViewSize(ImageView imageView) {    ImageSize imageSize = new ImageSize();    DisplayMetrics displayMetrics = imageView.getContext().getResources().getDisplayMetrics();    LayoutParams lp = imageView.getLayoutParams();    int width = imageView.getWidth();// 獲取imageview的實(shí)際寬度    if (lp != null) {      if (width <= 0) {        width = lp.width;// 獲取imageview在layout中聲明的寬度      }    }    if (width <= 0) {      // width = imageView.getMaxWidth();// 檢查最大值      width = getImageViewFieldValue(imageView, "mMaxWidth");    }    if (width <= 0) {      width = displayMetrics.widthPixels;    }    int height = imageView.getHeight();// 獲取imageview的實(shí)際高度    if (lp != null) {      if (height <= 0) {        height = lp.height;// 獲取imageview在layout中聲明的寬度      }    }    if (height <= 0) {      height = getImageViewFieldValue(imageView, "mMaxHeight");// 檢查最大值    }    if (height <= 0) {      height = displayMetrics.heightPixels;    }    imageSize.width = width;    imageSize.height = height;    return imageSize;  }  public static class ImageSize {    public int width;    public int height;  }  /**   * 通過反射獲取imageview的某個(gè)屬性值   *   * @param object   * @param fieldName   * @return   */  private static int getImageViewFieldValue(Object object, String fieldName) {    int value = 0;    try {      Field field = ImageView.class.getDeclaredField(fieldName);      field.setAccessible(true);      int fieldValue = field.getInt(object);      if (fieldValue > 0 && fieldValue < Integer.MAX_VALUE) {        value = fieldValue;      }    } catch (Exception e) {    }    return value;  }}

希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 平潭县| 虞城县| 察哈| 庆元县| 绥滨县| 雅安市| 肃宁县| 巩义市| 钟祥市| 桂东县| 仁化县| 盐津县| 双辽市| 庆元县| 天水市| 肥西县| 三亚市| 库伦旗| 阳江市| 天津市| 普格县| 益阳市| 南康市| 德江县| 巨鹿县| 缙云县| 宁南县| 宜良县| 理塘县| 凉城县| 临夏市| 禄丰县| 岑巩县| 肥西县| 留坝县| 兴安盟| 敖汉旗| 望奎县| 丰城市| 伊金霍洛旗| 永德县|