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

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

Android實現(xiàn)異步加載圖片

2019-10-23 18:29:24
字體:
供稿:網(wǎng)友

麥洛開通博客以來,有一段時間沒有更新博文了.主要是麥洛這段時間因項目開發(fā)實在太忙了.今天周六還在公司加班,苦逼程序猿都是這樣生活的.

今天在做項目的時候,有一個實現(xiàn)異步加載圖片的功能,雖然比較簡單但還是記錄一下吧.因為麥洛之前實現(xiàn)異步加載圖片都是使用了AsynTask這個API,繼續(xù)這個類,實現(xiàn)起來非常簡單也很方便.在doInBackground()方法里實現(xiàn)下載邏輯.具體實現(xiàn)如下

實現(xiàn)邏輯是:先從內(nèi)存中讀取,如果內(nèi)存中有這張圖片,則直接使用;如果內(nèi)存沒有再到sdcard上讀取,如果有則顯示;如果sdcard上還沒有則到網(wǎng)絡(luò)上讀取.內(nèi)存中開啟緩存是參考了網(wǎng)上的實現(xiàn).麥洛在這里非常感謝喜歡分享的程序猿們.

public class ImageDownloader extends AsyncTask<String, Integer, Object> {  private static final String TAG = "ImageDownloader";  // 為了加快速度,在內(nèi)存中開啟緩存(主要應(yīng)用于重復(fù)圖片較多時,或者同一個圖片要多次被訪問,比如在ListView時來回滾動)  private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();  /**   * 顯示圖片的控件   */  private ImageView mImageView;  public ImageDownloader(ImageView image) {    mImageView = image;  }  @Override  protected void onPreExecute() {    super.onPreExecute();  }  @Override  protected Object doInBackground(String... params) {    // Log.i("ImageDownloader", "loading image...");    String url = params[0];    Drawable drawable = null;    try {      if (!"".equals(url) && url != null) {        String fileName = url.hashCode()+".jpg";        // 如果緩存過就從緩存中取出數(shù)據(jù)        if (imageCache.containsKey(fileName)) {          SoftReference<Drawable> softReference = imageCache.get(fileName);          drawable = softReference.get();          if (drawable != null) {            return drawable;          }        }        File dir = new File(FileConstant.IMAGE_FILE_PATH);        if (!dir.exists()) {          boolean m = dir.mkdirs();        }        File file = new File(dir, fileName);        if (file.exists() && file.length() > 0) {          Log.i(TAG, "load image from sd card");          // 如果文件存在則直接讀取sdcard          drawable = readFromSdcard(file);        } else {          //file.createNewFile();          Log.i(TAG, "load image from network");          URL imageUrl = new URL(url);          // 寫入sdcard          if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            saveImageFile(imageUrl, file);            drawable = Drawable.createFromStream(new FileInputStream(file), fileName);          }else{            //直接從流讀取            drawable = Drawable.createFromStream(imageUrl.openStream(), fileName);          }        }        if(drawable!=null){          //保存在緩存中          imageCache.put(fileName, new SoftReference<Drawable>(drawable));        }      }    } catch (Exception e) {      e.printStackTrace();    }     return drawable;  }  /**   * save image*/  private void saveImageFile(URL url, File file) {    FileOutputStream out = null;    InputStream in = null;    try {      file.deleteOnExit();      out = new FileOutputStream(file);      in = url.openStream();      byte[] buf = new byte[1024];      int len = -1;      while((len = in.read(buf))!=-1){        out.write(buf, 0, len);        out.flush();      }    } catch (Exception e) {      e.printStackTrace();    } finally {      if(out!=null){        try {          out.close();        } catch (IOException e) {          e.printStackTrace();        }      }      if(in!=null){        try {          in.close();        } catch (IOException e) {          e.printStackTrace();        }      }    }  }  /**   * 從sdcard中獲取圖片*/  private Drawable readFromSdcard(File file) throws Exception {    FileInputStream in = new FileInputStream(file);    return Drawable.createFromStream(in, file.getName());  }  @Override  protected void onPostExecute(Object result) {    super.onPostExecute(result);    Drawable drawable = (Drawable) result;    if (mImageView != null && drawable != null) {      mImageView.setBackgroundDrawable(drawable);    }  }  @Override  protected void onProgressUpdate(Integer... values) {    super.onProgressUpdate(values);  }  @Override  protected void onCancelled() {    super.onCancelled();  }}

使用時:

ImageDownloader loader = new ImageDownloader(imageView);loader.execute(url);

其實這樣的話,還有一些隱患的,就是說這個類實現(xiàn)還是有些問題的.比如每次都在imageView中設(shè)置網(wǎng)絡(luò)上的圖片時,其實是沒有使用到這個類里面的內(nèi)存緩存的,就是imageCache

Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
因為每次設(shè)置imageView的時候,都是new了一個ImageDownloader的對象.所以每個ImageDownloader對象里面都是獨立的一個imageCache.

另外,AsynTask也是一個線程.而每次使用都開一個線程來load 圖片,對線程個數(shù)沒有進行顯示,畢竟線程數(shù)目還是有限制的.
所以麥洛今天發(fā)現(xiàn)了這個問題,于是參考了別人的實現(xiàn),使用了線程池,實現(xiàn)邏輯也上面的代碼一樣,先從內(nèi)存讀取,如果沒有到sdcard讀取,如果還是沒有,則是網(wǎng)絡(luò)讀取;實現(xiàn)沒有使用AsynTask,具體代碼如下:

/** * 異步加載圖片,并將圖片設(shè)置到ImageView控件中*/public class ImageDownloader extends AsyncTask<String, Integer, Object> {  private static final String TAG = "ImageDownloader";  // 為了加快速度,在內(nèi)存中開啟緩存(主要應(yīng)用于重復(fù)圖片較多時,或者同一個圖片要多次被訪問,比如在ListView時來回滾動)  private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();  /**   * 顯示圖片的控件   */  private ImageView mImageView;  public ImageDownloader(ImageView image) {    mImageView = image;  }  @Override  protected void onPreExecute() {    super.onPreExecute();  }  @Override  protected Object doInBackground(String... params) {    // Log.i("ImageDownloader", "loading image...");    String url = params[0];    Drawable drawable = null;    try {      if (!"".equals(url) && url != null) {        String fileName = url.hashCode()+".jpg";        // 如果緩存過就從緩存中取出數(shù)據(jù)        if (imageCache.containsKey(fileName)) {          SoftReference<Drawable> softReference = imageCache.get(fileName);          drawable = softReference.get();          if (drawable != null) {            return drawable;          }        }        File dir = new File(FileConstant.IMAGE_FILE_PATH);        if (!dir.exists()) {          boolean m = dir.mkdirs();        }        File file = new File(dir, fileName);        if (file.exists() && file.length() > 0) {          Log.i(TAG, "load image from sd card");          // 如果文件存在則直接讀取sdcard          drawable = readFromSdcard(file);        } else {          //file.createNewFile();          Log.i(TAG, "load image from network");          URL imageUrl = new URL(url);          // 寫入sdcard          if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            saveImageFile(imageUrl, file);            drawable = Drawable.createFromStream(new FileInputStream(file), fileName);          }else{            //直接從流讀取            drawable = Drawable.createFromStream(imageUrl.openStream(), fileName);          }        }        if(drawable!=null){          //保存在緩存中          imageCache.put(fileName, new SoftReference<Drawable>(drawable));        }      }    } catch (Exception e) {      e.printStackTrace();    }     return drawable;  }  /**   * save image*/  private void saveImageFile(URL url, File file) {    FileOutputStream out = null;    InputStream in = null;    try {      file.deleteOnExit();      out = new FileOutputStream(file);      in = url.openStream();      byte[] buf = new byte[1024];      int len = -1;      while((len = in.read(buf))!=-1){        out.write(buf, 0, len);        out.flush();      }    } catch (Exception e) {      e.printStackTrace();    } finally {      if(out!=null){        try {          out.close();        } catch (IOException e) {          e.printStackTrace();        }      }      if(in!=null){        try {          in.close();        } catch (IOException e) {          e.printStackTrace();        }      }    }  }  /**   * 從sdcard中獲取圖片 */  private Drawable readFromSdcard(File file) throws Exception {    FileInputStream in = new FileInputStream(file);    return Drawable.createFromStream(in, file.getName());  }  @Override  protected void onPostExecute(Object result) {    super.onPostExecute(result);    Drawable drawable = (Drawable) result;    if (mImageView != null && drawable != null) {      mImageView.setBackgroundDrawable(drawable);    }  }  @Override  protected void onProgressUpdate(Integer... values) {    super.onProgressUpdate(values);  }  @Override  protected void onCancelled() {    super.onCancelled();  }}

這個ImageDownloader2的使用也很簡單

public class ImageUtil {  /**   * image loader   */  static ImageDownloader2 loader = null;    /**   * load image*/  public static void loadImage(String url,final ImageView imageView){    if(loader == null){      loader = new ImageDownloader2();    }    loader.loadDrawable(url, new ImageCallback() {            @Override      public void imageLoaded(Drawable imageDrawable) {        if(imageDrawable!=null){          imageView.setBackgroundDrawable(imageDrawable);        }      }    });  }  }

每次在使用是需要調(diào)用ImageUtil.loadImage(url,imageView)將圖片url已經(jīng)需要顯示圖片的控件ImageView的引用傳入就可以了.

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 汝城县| 仁寿县| 招远市| 仁怀市| 正安县| 云安县| 汽车| 靖州| 清涧县| 习水县| 大竹县| 泸州市| 松潘县| 宁蒗| 贡嘎县| 林周县| 德阳市| 东阿县| 永顺县| 奎屯市| 宜都市| 双辽市| 晋城| 合肥市| 弋阳县| 双城市| 五莲县| 合作市| 南华县| 泽州县| 盈江县| 龙井市| 鸡西市| 井研县| 古浪县| 阿拉尔市| 宁德市| 商洛市| 郧西县| 漠河县| 永宁县|