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

在Android的應(yīng)用中實(shí)現(xiàn)網(wǎng)絡(luò)圖片異步加載的方法

 更新時(shí)間:2015年07月31日 15:50:59   作者:zinss26914  
這篇文章主要介紹了在Android的應(yīng)用中實(shí)現(xiàn)網(wǎng)絡(luò)圖片異步加載的方法,一定程度上有助于提高安卓程序的使用體驗(yàn),需要的朋友可以參考下

前言
其實(shí)很幸運(yùn),入職一周之后就能跟著兩個(gè)師兄做android開發(fā),師兄都是大神,身為小白的我只能多多學(xué)習(xí),多多努力。最近一段時(shí)間都忙的沒機(jī)會(huì)總結(jié),今天剛完成了android客戶端圖片異步加載的類,這里記錄一下(ps:其實(shí)我這里都是參考網(wǎng)上開源實(shí)現(xiàn))


原理
在ListView或者GridView中加載圖片的原理基本都是一樣的:

    先從內(nèi)存緩存中獲取,取到則返回,取不到進(jìn)行下一步
    從文件緩存中獲取,取到則返回并更新到內(nèi)存緩存,取不到則進(jìn)行進(jìn)行下一步
    從網(wǎng)絡(luò)上下載圖片,并更新內(nèi)存緩存和文件緩存


流程圖如下:

2015731154609726.png (636×512)

同時(shí),要注意線程的數(shù)量。一般在listview中加載圖片,大家都是開啟新的線程去加載,但是當(dāng)快速滑動(dòng)時(shí),很容易造成OOM,因此需要控制線程數(shù)量。我們可以通過線程池控制線程的數(shù)量,具體線程池的大小還需要根據(jù)處理器的情況和業(yè)務(wù)情況自行判斷

建立線程池的方法如下:

   

ExecutorService executorService = Executors.newFixedThreadPool(5); // 5是可變的 

文件緩存類

   

 import java.io.File; 
   
  import android.content.Context; 
   
  public class FileCache { 
    private static final String DIR_NAME = "your_dir"; 
    private File cacheDir; 
   
    public FileCache(Context context) { 
      // Find the directory to save cached images 
      if (android.os.Environment.getExternalStorageState().equals( 
          android.os.Environment.MEDIA_MOUNTED)) { 
        cacheDir = new File( 
            android.os.Environment.getExternalStorageDirectory(), 
            DIR_NAME); 
      } else { 
        cacheDir = context.getCacheDir(); 
      } 
   
      if (!cacheDir.exists()) { 
        cacheDir.mkdirs(); 
      } 
    } 
   
    public File getFile(String url) { 
      // Identify images by url's hash code 
      String filename = String.valueOf(url.hashCode()); 
   
      File f = new File(cacheDir, filename); 
   
      return f; 
    } 
   
    public void clear() { 
      File[] files = cacheDir.listFiles(); 
      if (files == null) { 
        return; 
      } else { 
        for (File f : files) { 
          f.delete(); 
        } 
      } 
    } 
  } 

內(nèi)存緩存類
這里使用了軟引用,Map<String, SoftReference<Bitmap>> cache,可以google一下軟引用的機(jī)制,簡單的說:實(shí)現(xiàn)了map,同時(shí)當(dāng)內(nèi)存緊張時(shí)可以被回收,不會(huì)造成內(nèi)存泄露

   

 import java.lang.ref.SoftReference; 
  import java.util.Collections; 
  import java.util.LinkedHashMap; 
  import java.util.Map; 
   
  import android.graphics.Bitmap; 
   
  public class MemoryCache { 
    private Map<String, SoftReference<Bitmap>> cache = Collections 
        .synchronizedMap(new LinkedHashMap<String, SoftReference<Bitmap>>( 
            10, 1.5f, true)); 
   
    public Bitmap get(String id) { 
      if (!cache.containsKey(id)) { 
        return null; 
      } 
   
      SoftReference<Bitmap> ref = cache.get(id); 
   
      return ref.get(); 
    } 
   
    public void put(String id, Bitmap bitmap) { 
      cache.put(id, new SoftReference<Bitmap>(bitmap)); 
    } 
   
    public void clear() { 
      cache.clear(); 
    } 
  } 

圖片加載類

  import java.io.File; 
  import java.io.FileInputStream; 
  import java.io.FileNotFoundException; 
  import java.io.FileOutputStream; 
  import java.io.InputStream; 
  import java.io.OutputStream; 
  import java.net.HttpURLConnection; 
  import java.net.URL; 
  import java.util.Collections; 
  import java.util.Map; 
  import java.util.WeakHashMap; 
  import java.util.concurrent.ExecutorService; 
  import java.util.concurrent.Executors; 
   
  import android.content.Context; 
  import android.graphics.Bitmap; 
  import android.graphics.BitmapFactory; 
  import android.os.Handler; 
  import android.widget.ImageView; 
   
  public class ImageLoader { 
    /** 
     * Network time out 
     */ 
    private static final int TIME_OUT = 30000; 
    /** 
     * Default picture resource 
     */ 
    private static final int DEFAULT_BG = R.drawable.plate_list_head_bg; 
   
    /** 
     * Thread pool number 
     */ 
    private static final int THREAD_NUM = 5; 
   
    /** 
     * Memory image cache 
     */ 
    MemoryCache memoryCache = new MemoryCache(); 
   
    /** 
     * File image cache 
     */ 
    FileCache fileCache; 
   
    /** 
     * Judge image view if it is reuse 
     */ 
    private Map<ImageView, String> imageViews = Collections 
        .synchronizedMap(new WeakHashMap<ImageView, String>()); 
   
    /** 
     * Thread pool 
     */ 
    ExecutorService executorService; 
   
    /** 
     * Handler to display images in UI thread 
     */ 
    Handler handler = new Handler(); 
   
    public ImageLoader(Context context) { 
      fileCache = new FileCache(context); 
      executorService = Executors.newFixedThreadPool(THREAD_NUM); 
    } 
   
    public void disPlayImage(String url, ImageView imageView) { 
      imageViews.put(imageView, url); 
      Bitmap bitmap = memoryCache.get(url); 
      if (bitmap != null) { 
        // Display image from Memory cache 
        imageView.setImageBitmap(bitmap); 
      } else { 
        // Display image from File cache or Network 
        queuePhoto(url, imageView); 
      } 
    } 
   
    private void queuePhoto(String url, ImageView imageView) { 
      PhotoToLoad photoToLoad = new PhotoToLoad(url, imageView); 
      executorService.submit(new PhotosLoader(photoToLoad)); 
    } 
   
    private Bitmap getBitmap(String url) { 
      File f = fileCache.getFile(url); 
   
      // From File cache 
      Bitmap bmp = decodeFile(f); 
      if (bmp != null) { 
        return bmp; 
      } 
   
      // From Network 
      try { 
        Bitmap bitmap = null; 
        URL imageUrl = new URL(url); 
        HttpURLConnection conn = (HttpURLConnection) imageUrl 
            .openConnection(); 
        conn.setConnectTimeout(TIME_OUT); 
        conn.setReadTimeout(TIME_OUT); 
        conn.setInstanceFollowRedirects(true); 
        InputStream is = conn.getInputStream(); 
        OutputStream os = new FileOutputStream(f); 
        copyStream(is, os); 
        os.close(); 
        conn.disconnect(); 
        bitmap = decodeFile(f); 
        return bitmap; 
      } catch (Throwable ex) { 
        if (ex instanceof OutOfMemoryError) { 
          clearCache(); 
        } 
        return null; 
      } 
   
    } 
   
    private void copyStream(InputStream is, OutputStream os) { 
      int buffer_size = 1024; 
   
      try { 
        byte[] bytes = new byte[buffer_size]; 
        while (true) { 
          int count = is.read(bytes, 0, buffer_size); 
          if (count == -1) { 
            break; 
          } 
          os.write(bytes, 0, count); 
        } 
   
      } catch (Exception e) { 
   
      } 
    } 
   
    private Bitmap decodeFile(File f) { 
      try { 
        // TODO:Compress image size 
        FileInputStream fileInputStream = new FileInputStream(f); 
        Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream); 
        return bitmap; 
   
      } catch (FileNotFoundException e) { 
        return null; 
      } 
    } 
   
    private void clearCache() { 
      memoryCache.clear(); 
      fileCache.clear(); 
    } 
   
    /** 
     * Task for the queue 
     * 
     * @author zhengyi.wzy 
     * 
     */ 
    private class PhotoToLoad { 
      public String url; 
      public ImageView imageView; 
   
      public PhotoToLoad(String url, ImageView imageView) { 
        this.url = url; 
        this.imageView = imageView; 
      } 
    } 
   
    /** 
     * Asynchronous to load picture 
     * 
     * @author zhengyi.wzy 
     * 
     */ 
    class PhotosLoader implements Runnable { 
      PhotoToLoad photoToLoad; 
   
      public PhotosLoader(PhotoToLoad photoToLoad) { 
        this.photoToLoad = photoToLoad; 
      } 
   
      private boolean imageViewReused(PhotoToLoad photoToLoad) { 
        String tag = imageViews.get(photoToLoad.imageView); 
        if (tag == null || !tag.equals(photoToLoad.url)) { 
          return true; 
        } 
   
        return false; 
      } 
   
      @Override 
      public void run() { 
        // Abort current thread if Image View reused 
        if (imageViewReused(photoToLoad)) { 
          return; 
        } 
   
        Bitmap bitmap = getBitmap(photoToLoad.url); 
   
        // Update Memory 
        memoryCache.put(photoToLoad.url, bitmap); 
   
        if (imageViewReused(photoToLoad)) { 
          return; 
        } 
   
        // Don't change UI in children thread 
        BitmapDisplayer bd = new BitmapDisplayer(bitmap, photoToLoad); 
        handler.post(bd); 
      } 
   
      class BitmapDisplayer implements Runnable { 
        Bitmap bitmap; 
        PhotoToLoad photoToLoad; 
   
        public BitmapDisplayer(Bitmap bitmap, PhotoToLoad photoToLoad) { 
          this.bitmap = bitmap; 
          this.photoToLoad = photoToLoad; 
        } 
   
        @Override 
        public void run() { 
          if (imageViewReused(photoToLoad)) { 
            return; 
          } 
   
          if (bitmap != null) { 
            photoToLoad.imageView.setImageBitmap(bitmap); 
          } else { 
            photoToLoad.imageView.setImageResource(DEFAULT_BG); 
          } 
        } 
   
      } 
    } 
  } 

調(diào)用方法

  ImageLoader imageLoader = new ImageLoader(context); 
  imageLoader.disPlayImage(imageUrl, imageView); 


相關(guān)文章

  • SpringBoot配置文件的加載位置實(shí)例詳解

    SpringBoot配置文件的加載位置實(shí)例詳解

    springboot采納了建立生產(chǎn)就緒spring應(yīng)用程序的觀點(diǎn)。 在一些特殊的情況下,我們需要做修改一些配置,或者需要有自己的配置屬性。接下來通過本文給大家介紹SpringBoot配置文件的加載位置,感興趣的朋友一起看看吧
    2018-09-09
  • Java實(shí)現(xiàn)整數(shù)分解質(zhì)因數(shù)的方法示例

    Java實(shí)現(xiàn)整數(shù)分解質(zhì)因數(shù)的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)整數(shù)分解質(zhì)因數(shù)的方法,結(jié)合實(shí)力形式分析了質(zhì)因數(shù)分解的原理與實(shí)現(xiàn)方法,涉及java數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • SpringBoot給類進(jìn)行賦初值的四種方式

    SpringBoot給類進(jìn)行賦初值的四種方式

    這篇文章主要介紹了springboot給類進(jìn)行賦初值的四種方式,并通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-08-08
  • why在重寫equals時(shí)還必須重寫hashcode方法分享

    why在重寫equals時(shí)還必須重寫hashcode方法分享

    首先我們先來看下String類的源碼:可以發(fā)現(xiàn)String是重寫了Object類的equals方法的,并且也重寫了hashcode方法
    2013-10-10
  • 解決response.setHeader設(shè)置下載文件名無效的問題

    解決response.setHeader設(shè)置下載文件名無效的問題

    這篇文章主要介紹了解決response.setHeader設(shè)置下載文件名無效的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的示例

    MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的示例

    本文主要介紹了MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Java深入淺出理解快速排序以及優(yōu)化方式

    Java深入淺出理解快速排序以及優(yōu)化方式

    快速排序由于排序效率在同為O(N*logN)的幾種排序方法中效率較高,因此經(jīng)常被采用,再加上快速排序思想----分治法也確實(shí)實(shí)用,因此很多軟件公司的筆試面試,包括像騰訊,微軟等知名IT公司都喜歡考這個(gè),還有大大小的程序方面的考試如軟考,考研中也常常出現(xiàn)快速排序的身影
    2021-11-11
  • SpringMVC接收與響應(yīng)json數(shù)據(jù)的幾種方式

    SpringMVC接收與響應(yīng)json數(shù)據(jù)的幾種方式

    這篇文章主要給大家介紹了關(guān)于SpringMVC接收與響應(yīng)json數(shù)據(jù)的幾種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用springmvc具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 解決HttpServletRequest 流數(shù)據(jù)不可重復(fù)讀的操作

    解決HttpServletRequest 流數(shù)據(jù)不可重復(fù)讀的操作

    這篇文章主要介紹了解決HttpServletRequest 流數(shù)據(jù)不可重復(fù)讀的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java的基礎(chǔ)語法學(xué)習(xí)筆記

    Java的基礎(chǔ)語法學(xué)習(xí)筆記

    這里為大家整理了Java的基礎(chǔ)語法學(xué)習(xí)筆記,包括關(guān)鍵詞、運(yùn)算符與基本的流程控制語句寫法等,需要的朋友可以參考下
    2016-05-05

最新評論

陆河县| 安塞县| 察哈| 祥云县| 隆昌县| 蒙自县| 广昌县| 包头市| 綦江县| 墨玉县| 杭锦后旗| 中江县| 朝阳县| 株洲县| 始兴县| 宁强县| 张家港市| 汉中市| 道孚县| 营山县| 岳阳市| 西平县| 萨迦县| 犍为县| 永丰县| 汾阳市| 吐鲁番市| 麻阳| 开远市| 鄂托克前旗| 华阴市| 陵川县| 米林县| 江阴市| 阿克苏市| 苍山县| 衡山县| 禄丰县| 尉氏县| 景谷| 白山市|