激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

香港云服务器
服務(wù)器之家 - 編程語言 - JAVA教程 - 在Android的應(yīng)用中實(shí)現(xiàn)網(wǎng)絡(luò)圖片異步加載的方法

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

2019-12-31 14:50zinss26914 JAVA教程

這篇文章主要介紹了在Android的應(yīng)用中實(shí)現(xiàn)網(wǎng)絡(luò)圖片異步加載的方法,一定程度上有助于提高安卓程序的使用體驗(yàn),需要的朋友可以參考下

前言
其實(shí)很幸運(yùn),入職一周之后就能跟著兩個師兄做android開發(fā),師兄都是大神,身為小白的我只能多多學(xué)習(xí),多多努力。最近一段時間都忙的沒機(jī)會總結(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)存緩存和文件緩存


流程圖如下:

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

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

建立線程池的方法如下:

   

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

文件緩存類

   

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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,同時當(dāng)內(nèi)存緊張時可以被回收,不會造成內(nèi)存泄露

   

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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();
   }
 }

圖片加載類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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)用方法

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

 

延伸 · 閱讀

精彩推薦
571
主站蜘蛛池模板: 综合网天天色 | 美女一级毛片 | 黄色片视频免费观看 | 欧美亚洲免费 | 国产免费人做人爱午夜视频 | 最新日韩中文字幕 | 精品国产精品久久 | 九九久久视频 | 欧美久久久久久久久 | 国产在线精品一区二区夜色 | 久久久久国产一区二区三区不卡 | 国产乱淫av片免费 | 免费观看一级黄色片 | 色婷婷一区二区三区 | 国产精品视频在 | 精品欧美一区二区精品久久 | 日本不卡一二三区 | 99精品视频免费 | 免费看操片 | 看国产精品 | 国产成人精品免费视频大全最热 | 欧洲黄色一级视频 | 国产亲子伦在线观看 | 日本久久网站 | 国产18视频 | 91精品国产九九九久久久亚洲 | 黄色电影免费网址 | 免费国产wwwwwww网站 | 免费a视频在线观看 | 欧洲亚洲激情 | 白天操夜夜操 | 免费久久久久久 | 久久久国产电影 | 亚洲一区二区三区高清视频 | 亚洲精品午夜国产va久久成人 | 麻豆视频在线免费观看 | 91久久99热青草国产 | 免费毛片免费看 | 欧美韩国一区 | 色人阁在线视频 | 日韩.www |