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

首頁(yè) > 編程 > Java > 正文

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

2019-11-26 15:02:04
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言
其實(shí)很幸運(yùn),入職一周之后就能跟著兩個(gè)師兄做android開(kāi)發(fā),師兄都是大神,身為小白的我只能多多學(xué)習(xí),多多努力。最近一段時(shí)間都忙的沒(méi)機(jī)會(huì)總結(jié),今天剛完成了android客戶端圖片異步加載的類,這里記錄一下(ps:其實(shí)我這里都是參考網(wǎng)上開(kāi)源實(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中加載圖片,大家都是開(kāi)啟新的線程去加載,但是當(dāng)快速滑動(dòng)時(shí),很容易造成OOM,因此需要控制線程數(shù)量。我們可以通過(guò)線程池控制線程的數(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ī)制,簡(jiǎn)單的說(shuō):實(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); 

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 页游| 牙克石市| 昆山市| 桓台县| 安平县| 高要市| 积石山| 永年县| 贵南县| 军事| 永福县| 和龙市| 潍坊市| 周至县| 方正县| 安顺市| 浮山县| 大渡口区| 岫岩| 安宁市| 高尔夫| 手游| 宜川县| 大关县| 贵溪市| 伊金霍洛旗| 仁怀市| 灵宝市| 凤庆县| 阿瓦提县| 绿春县| 河北省| 南召县| 泰顺县| 荣昌县| 青田县| 彩票| 临海市| 巴彦县| 江西省| 竹山县|