最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2017年05月08日 11:58:02   作者:趙大海  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)異步加載圖片的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

今天在做項(xiàng)目的時(shí)候,有一個(gè)實(shí)現(xiàn)異步加載圖片的功能,雖然比較簡(jiǎn)單但還是記錄一下吧.因?yàn)辂溌逯皩?shí)現(xiàn)異步加載圖片都是使用了AsynTask這個(gè)API,繼續(xù)這個(gè)類,實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單也很方便.在doInBackground()方法里實(shí)現(xiàn)下載邏輯.具體實(shí)現(xiàn)如下

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

public class ImageDownloader extends AsyncTask<String, Integer, Object> {

  private static final String TAG = "ImageDownloader";
  // 為了加快速度,在內(nèi)存中開啟緩存(主要應(yīng)用于重復(fù)圖片較多時(shí),或者同一個(gè)圖片要多次被訪問(wèn),比如在ListView時(shí)來(lái)回滾動(dòng))
  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";
        // 如果緩存過(guò)就從緩存中取出數(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();
  }

}

使用時(shí):

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

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

Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
因?yàn)槊看卧O(shè)置imageView的時(shí)候,都是new了一個(gè)ImageDownloader的對(duì)象.所以每個(gè)ImageDownloader對(duì)象里面都是獨(dú)立的一個(gè)imageCache.

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

/**
 * 異步加載圖片,并將圖片設(shè)置到ImageView控件中
*/
public class ImageDownloader extends AsyncTask<String, Integer, Object> {

  private static final String TAG = "ImageDownloader";
  // 為了加快速度,在內(nèi)存中開啟緩存(主要應(yīng)用于重復(fù)圖片較多時(shí),或者同一個(gè)圖片要多次被訪問(wèn),比如在ListView時(shí)來(lái)回滾動(dòng))
  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";
        // 如果緩存過(guò)就從緩存中取出數(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();
  }

}

這個(gè)ImageDownloader2的使用也很簡(jiǎn)單

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的引用傳入就可以了.

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

塘沽区| 阿尔山市| 南靖县| 积石山| 阆中市| 金寨县| 习水县| 北安市| 甘洛县| 横山县| 靖宇县| 金川县| 信阳市| 大埔区| 海盐县| 梨树县| 承德市| 枞阳县| 新安县| 盈江县| 万全县| 诸城市| 德格县| 永德县| 浦北县| 巴东县| 金川县| 尤溪县| 崇阳县| 陵川县| 涞水县| 南京市| 筠连县| 怀远县| 西华县| 永登县| 惠州市| 屏山县| 精河县| 洛南县| 延安市|