一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

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

服務器之家 - 編程語言 - JAVA教程 - 在Android的應用中實現網絡圖片異步加載的方法

在Android的應用中實現網絡圖片異步加載的方法

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

這篇文章主要介紹了在Android的應用中實現網絡圖片異步加載的方法,一定程度上有助于提高安卓程序的使用體驗,需要的朋友可以參考下

前言
其實很幸運,入職一周之后就能跟著兩個師兄做android開發,師兄都是大神,身為小白的我只能多多學習,多多努力。最近一段時間都忙的沒機會總結,今天剛完成了android客戶端圖片異步加載的類,這里記錄一下(ps:其實我這里都是參考網上開源實現)


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

    先從內存緩存中獲取,取到則返回,取不到進行下一步
    從文件緩存中獲取,取到則返回并更新到內存緩存,取不到則進行進行下一步
    從網絡上下載圖片,并更新內存緩存和文件緩存


流程圖如下:

在Android的應用中實現網絡圖片異步加載的方法

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

建立線程池的方法如下:

   

?
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();
       }
     }
   }
 }

內存緩存類
這里使用了軟引用,Map<String, SoftReference<Bitmap>> cache,可以google一下軟引用的機制,簡單的說:實現了map,同時當內存緊張時可以被回收,不會造成內存泄露

   

?
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);
        }
      }
 
    }
  }
}

 

調用方法

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

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本高清在线播放 | 欧美性一级交视频 | 精品久久久久久亚洲精品 | 好吊色青青青国产综合在线观看 | 男女性潮高片无遮挡禁18 | 草草影院在线 | 日韩欧美亚洲一区二区综合 | 免费看打屁股视频的软件 | 精品一区heyzo在线播放 | 国产二区视频在线观看 | 欧美同性猛男videos | 日本乱人伦中文在线播放 | 国产极品麻豆91在线 | 韩国悲惨事件30无删减在线 | 九九精品国产兔费观看久久 | 91九色porny国产美女一区 | 久久www免费人成高清 | 精品一区heyzo在线播放 | 久久毛片免费看一区二区三区 | 美女用手扒开粉嫩的屁股 | 日韩亚洲欧美一区二区三区 | 国产一区二区三区四 | 天天色综合久久 | 国产精品亚洲专区在线播放 | 亚洲国产美女精品久久久久 | 欧美日韩精 | 我将她侵犯1~6樱花动漫在线看 | 国产黄频在线观看高清免费 | 本站只有精品 | 男女性gif抽搐出入视频 | 欧美一级级a在线观看 | 97porm自拍视频区原创 | 草莓茄子丝瓜番茄小蝌蚪 | 亚洲欧美在线观看首页 | 3d欧美人禽交 | 国语自产拍在线观看7m | 日本高清视频一区二区 | 奇米影视久久 | 日产2021免费一二三四区 | 国产精品露脸国语对白手机视频 | 插鸡视频在线观看 |