3. Android框架和工具之 xUtils(BitmapUtils)

1. BitmapUtils 作用:

  • 加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象;
  • 支持加载网络图片和本地图片;
  • 内存管理使用lru算法,更好的管理bitmap内存;
  • 可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等...

 

2. BitmapUtils 全面注释:

  1 /**
  2  * 加载图片工具类
  3  * @author afu
  4  *
  5  */
  6 public class BitmapUtils implements TaskHandler {
  7 
  8     /**
  9      * 判断任务是否暂停
 10      */
 11     private boolean pauseTask = false;
 12     /**
 13      * 是否取消所有任务
 14      */
 15     private boolean cancelAllTask = false;
 16     private final Object pauseTaskLock = new Object();
 17 
 18     /**
 19      * Android上下文
 20      */
 21     private Context context;
 22     private BitmapGlobalConfig globalConfig;
 23     private BitmapDisplayConfig defaultDisplayConfig;
 24 
 25     /////////////////////////////////////////////// create ///////////////////////////////////////////////////
 26     /**
 27      * 
 28      * @param context 上下文
 29      */
 30     public BitmapUtils(Context context) {
 31         this(context, null);
 32     }
 33 
 34     /**
 35      * 
 36      * @param context 上下文
 37      * @param diskCachePath 磁盘高速缓存路径
 38      */
 39     public BitmapUtils(Context context, String diskCachePath) {
 40         if (context == null) {
 41             throw new IllegalArgumentException("context may not be null");
 42         }
 43 
 44         this.context = context.getApplicationContext();
 45         globalConfig = BitmapGlobalConfig.getInstance(this.context, diskCachePath);
 46         defaultDisplayConfig = new BitmapDisplayConfig();
 47     }
 48 
 49     /**
 50      * 
 51      * @param context 上下文
 52      * @param diskCachePath 磁盘高速缓存路径
 53      * @param memoryCacheSize 内存缓存空间大小
 54      */
 55     public BitmapUtils(Context context, String diskCachePath, int memoryCacheSize) {
 56         this(context, diskCachePath);
 57         globalConfig.setMemoryCacheSize(memoryCacheSize);
 58     }
 59 
 60     /**
 61      * 
 62      * @param context 上下文
 63      * @param diskCachePath 磁盘高速缓存路径
 64      * @param memoryCacheSize 内存缓存空间大小
 65      * @param diskCacheSize 磁盘高速缓存空间大小
 66      */
 67     public BitmapUtils(Context context, String diskCachePath, int memoryCacheSize, int diskCacheSize) {
 68         this(context, diskCachePath);
 69         globalConfig.setMemoryCacheSize(memoryCacheSize);
 70         globalConfig.setDiskCacheSize(diskCacheSize);
 71     }
 72 
 73     /**
 74      * 
 75      * @param context 上下文
 76      * @param diskCachePath 磁盘高速缓存路径
 77      * @param memoryCachePercent 内存缓存百分比
 78      */
 79     public BitmapUtils(Context context, String diskCachePath, float memoryCachePercent) {
 80         this(context, diskCachePath);
 81         globalConfig.setMemCacheSizePercent(memoryCachePercent);
 82     }
 83 
 84     /**
 85      * 
 86      * @param context 上下文
 87      * @param diskCachePath  磁盘高速缓存路径
 88      * @param memoryCachePercent 内存缓存百分比
 89      * @param diskCacheSize 磁盘缓存空间大小
 90      */
 91     public BitmapUtils(Context context, String diskCachePath, float memoryCachePercent, int diskCacheSize) {
 92         this(context, diskCachePath);
 93         globalConfig.setMemCacheSizePercent(memoryCachePercent);
 94         globalConfig.setDiskCacheSize(diskCacheSize);
 95     }
 96 
 97     //////////////////////////////////////// config  配置////////////////////////////////////////////////////////////////////
 98 
 99     /**
100      * 配置默认加载drawable类型资源图片
101      * @param drawable
102      * @return
103      */
104     public BitmapUtils configDefaultLoadingImage(Drawable drawable) {
105         defaultDisplayConfig.setLoadingDrawable(drawable);
106         return this;
107     }
108 
109     /**
110      * 配置默认加载资源id类型资源图片
111      * @param resId
112      * @return
113      */
114     public BitmapUtils configDefaultLoadingImage(int resId) {
115         defaultDisplayConfig.setLoadingDrawable(context.getResources().getDrawable(resId));
116         return this;
117     }
118 
119     /**
120      * 配置默认加载图片
121      * @param bitmap bitmap类中的资源图片
122      * @return
123      */
124     public BitmapUtils configDefaultLoadingImage(Bitmap bitmap) {
125         defaultDisplayConfig.setLoadingDrawable(new BitmapDrawable(context.getResources(), bitmap));
126         return this;
127     }
128 
129     /**
130      * 设置默认加载失败的图片
131      * @param drawable drawable类型的资源图片
132      * @return
133      */
134     public BitmapUtils configDefaultLoadFailedImage(Drawable drawable) {
135         defaultDisplayConfig.setLoadFailedDrawable(drawable);
136         return this;
137     }
138 
139     /**
140      * 配置默认加载失败图片,加载id类型资源图片
141      * @param resId
142      * @return
143      */
144     public BitmapUtils configDefaultLoadFailedImage(int resId) {
145         defaultDisplayConfig.setLoadFailedDrawable(context.getResources().getDrawable(resId));
146         return this;
147     }
148 
149     /**
150      * 配置默认加载失败图片,加载Bitmap类型资源图片
151      * @param bitmap
152      * @return
153      */
154     public BitmapUtils configDefaultLoadFailedImage(Bitmap bitmap) {
155         defaultDisplayConfig.setLoadFailedDrawable(new BitmapDrawable(context.getResources(), bitmap));
156         return this;
157     }
158 
159     /**
160      * 配置默认图片最大宽和高
161      * @param maxWidth 最大宽
162      * @param maxHeight 最大高
163      * @return
164      */
165     public BitmapUtils configDefaultBitmapMaxSize(int maxWidth, int maxHeight) {
166         defaultDisplayConfig.setBitmapMaxSize(new BitmapSize(maxWidth, maxHeight));
167         return this;
168     }
169 
170     /**
171      * 配置默认位图最大图片参数
172      * @param maxSize 最大图片参数类
173      * @return
174      */
175     public BitmapUtils configDefaultBitmapMaxSize(BitmapSize maxSize) {
176         defaultDisplayConfig.setBitmapMaxSize(maxSize);
177         return this;
178     }
179 
180     /**
181      * 配置默认图片加载动画
182      * @param animation 动画
183      * @return
184      */
185     public BitmapUtils configDefaultImageLoadAnimation(Animation animation) {
186         defaultDisplayConfig.setAnimation(animation);
187         return this;
188     }
189 
190     /**
191      * 配置默认自动旋转动画
192      * @param autoRotation
193      * @return
194      */
195     public BitmapUtils configDefaultAutoRotation(boolean autoRotation) {
196         defaultDisplayConfig.setAutoRotation(autoRotation);
197         return this;
198     }
199 
200     /**
201      * 配置默认是否显示原始图片
202      * @param showOriginal true:显示原始图片,false:将会对图片压缩处理
203      * @return
204      */
205     public BitmapUtils configDefaultShowOriginal(boolean showOriginal) {
206         defaultDisplayConfig.setShowOriginal(showOriginal);
207         return this;
208     }
209 
210     /**
211      * 配置默认图片配置,传入Bitmap.Config类型
212      * @param config
213      * @return
214      */
215     public BitmapUtils configDefaultBitmapConfig(Bitmap.Config config) {
216         defaultDisplayConfig.setBitmapConfig(config);
217         return this;
218     }
219 
220     /**
221      * 配置默认显示配置
222      * @param displayConfig
223      * @return
224      */
225     public BitmapUtils configDefaultDisplayConfig(BitmapDisplayConfig displayConfig) {
226         defaultDisplayConfig = displayConfig;
227         return this;
228     }
229 
230     /**
231      * 配置下载参数
232      * @param downloader
233      * @return
234      */
235     public BitmapUtils configDownloader(Downloader downloader) {
236         globalConfig.setDownloader(downloader);
237         return this;
238     }
239 
240     /**
241      * 配置默认缓存失效
242      * @param defaultExpiry
243      * @return
244      */
245     public BitmapUtils configDefaultCacheExpiry(long defaultExpiry) {
246         globalConfig.setDefaultCacheExpiry(defaultExpiry);
247         return this;
248     }
249 
250     /**
251      * 配置默认链接时间超时时间
252      * @param connectTimeout  毫秒单位
253      * @return
254      */
255     public BitmapUtils configDefaultConnectTimeout(int connectTimeout) {
256         globalConfig.setDefaultConnectTimeout(connectTimeout);
257         return this;
258     }
259 
260     /**
261      * 配置默认读取超时时间
262      * @param readTimeout 毫秒
263      * @return
264      */
265     public BitmapUtils configDefaultReadTimeout(int readTimeout) {
266         globalConfig.setDefaultReadTimeout(readTimeout);
267         return this;
268     }
269 
270     /**
271      * 配置线程池多少
272      * @param threadPoolSize 线程池数
273      * 此参数没有设置,默认是设置5个核心线程池
274      * @return
275      */
276     public BitmapUtils configThreadPoolSize(int threadPoolSize) {
277         globalConfig.setThreadPoolSize(threadPoolSize);
278         return this;
279     }
280 
281     /**
282      * 配置内存缓存是否启用,默认是启用的
283      * @param enabled
284      * @return
285      */
286     public BitmapUtils configMemoryCacheEnabled(boolean enabled) {
287         globalConfig.setMemoryCacheEnabled(enabled);
288         return this;
289     }
290 
291     /**
292      * 配置磁盘缓存功能,默认是启用的
293      * @param enabled
294      * @return
295      */
296     public BitmapUtils configDiskCacheEnabled(boolean enabled) {
297         globalConfig.setDiskCacheEnabled(enabled);
298         return this;
299     }
300 
301     /**
302      * 配置原始磁盘缓存文件名称
303      * @param fileNameGenerator
304      * @return
305      */
306     public BitmapUtils configDiskCacheFileNameGenerator(FileNameGenerator fileNameGenerator) {
307         globalConfig.setFileNameGenerator(fileNameGenerator);
308         return this;
309     }
310 
311     /**
312      * 配置位图缓存监听
313      * @param listener
314      * @return
315      */
316     public BitmapUtils configBitmapCacheListener(BitmapCacheListener listener) {
317         globalConfig.setBitmapCacheListener(listener);
318         return this;
319     }
320 
321     ////////////////////////// display  显示////////////////////////////////////
322 
323     /**
324      * 根据图片路径,显示到具体的View上
325      * @param container 要把图片显示到的View
326      * @param uri 图片路径
327      */
328     public <T extends View> void display(T container, String uri) {
329         display(container, uri, null, null);
330     }
331 
332     /**
333      * 根据图片路径,显示到具体的View上
334      * @param container 要把图片显示到的View
335      * @param uri 图片路径
336      * @param displayConfig
337      */
338     public <T extends View> void display(T container, String uri, BitmapDisplayConfig displayConfig) {
339         display(container, uri, displayConfig, null);
340     }
341 
342     /**
343      * 根据图片路径,显示到具体的View上
344      * @param container 要把图片显示到的View
345      * @param uri 图片路径
346      * @param callBack 加载过程回调各种状态
347      */
348     public <T extends View> void display(T container, String uri, BitmapLoadCallBack<T> callBack) {
349         display(container, uri, null, callBack);
350     }
351 
352     /**
353      * 根据图片路径,显示到具体的View上
354      * @param container 要把图片显示到的View
355      * @param uri 图片路径
356      * @param displayConfig 位图显示配置
357      * @param callBack
358      */
359     public <T extends View> void display(T container, String uri, BitmapDisplayConfig displayConfig, BitmapLoadCallBack<T> callBack) {
360         if (container == null) {
361             return;
362         }
363 
364         if (callBack == null) {
365             callBack = new DefaultBitmapLoadCallBack<T>();
366         }
367 
368         if (displayConfig == null || displayConfig == defaultDisplayConfig) {
369             displayConfig = defaultDisplayConfig.cloneNew();
370         }
371 
372         // Optimize Max Size
373         BitmapSize size = displayConfig.getBitmapMaxSize();
374         displayConfig.setBitmapMaxSize(BitmapCommonUtils.optimizeMaxSizeByView(container, size.getWidth(), size.getHeight()));
375 
376         container.clearAnimation();
377 
378         if (TextUtils.isEmpty(uri)) {
379             callBack.onLoadFailed(container, uri, displayConfig.getLoadFailedDrawable());
380             return;
381         }
382 
383         // start loading
384         callBack.onPreLoad(container, uri, displayConfig);
385 
386         // find bitmap from mem cache.
387         Bitmap bitmap = globalConfig.getBitmapCache().getBitmapFromMemCache(uri, displayConfig);
388 
389         if (bitmap != null) {
390             callBack.onLoadStarted(container, uri, displayConfig);
391             callBack.onLoadCompleted(
392                     container,
393                     uri,
394                     bitmap,
395                     displayConfig,
396                     BitmapLoadFrom.MEMORY_CACHE);
397         } else if (!bitmapLoadTaskExist(container, uri, callBack)) {
398 
399             final BitmapLoadTask<T> loadTask = new BitmapLoadTask<T>(container, uri, displayConfig, callBack);
400 
401             // get executor
402             PriorityExecutor executor = globalConfig.getBitmapLoadExecutor();
403             File diskCacheFile = this.getBitmapFileFromDiskCache(uri);
404             boolean diskCacheExist = diskCacheFile != null && diskCacheFile.exists();
405             if (diskCacheExist && executor.isBusy()) {
406                 executor = globalConfig.getDiskCacheExecutor();
407             }
408             // set loading image
409             Drawable loadingDrawable = displayConfig.getLoadingDrawable();
410             callBack.setDrawable(container, new AsyncDrawable<T>(loadingDrawable, loadTask));
411 
412             loadTask.setPriority(displayConfig.getPriority());
413             loadTask.executeOnExecutor(executor);
414         }
415     }
416 
417     /////////////////////////////////////////////// cache  缓存相关/////////////////////////////////////////////////////////////////
418 
419     /**
420      * 清除内存和磁盘缓存
421      */
422     public void clearCache() {
423         globalConfig.clearCache();
424     }
425 
426     /**
427      * 清除内存缓存
428      */
429     public void clearMemoryCache() {
430         globalConfig.clearMemoryCache();
431     }
432 
433     /**
434      * 清除磁盘缓存
435      */
436     public void clearDiskCache() {
437         globalConfig.clearDiskCache();
438     }
439 
440     /**
441      * 根据uri清除内存缓存和磁盘缓存
442      * @param uri
443      */
444     public void clearCache(String uri) {
445         globalConfig.clearCache(uri);
446     }
447 
448     /**
449      * 根据uri清除内存缓存
450      * @param uri
451      */
452     public void clearMemoryCache(String uri) {
453         globalConfig.clearMemoryCache(uri);
454     }
455 
456     /**
457      * 根据uri清除磁盘缓存
458      * @param uri
459      */
460     public void clearDiskCache(String uri) {
461         globalConfig.clearDiskCache(uri);
462     }
463 
464     /**
465      * 刷新缓存
466      */
467     public void flushCache() {
468         globalConfig.flushCache();
469     }
470 
471     /**
472      * 关闭缓存
473      */
474     public void closeCache() {
475         globalConfig.closeCache();
476     }
477 
478     /**
479      * 根据uri从磁盘缓存得到位图文件
480      * @param uri
481      * @return
482      */
483     public File getBitmapFileFromDiskCache(String uri) {
484         return globalConfig.getBitmapCache().getBitmapFileFromDiskCache(uri);
485     }
486 
487     /**
488      * 根据uri和位图显示配置从磁盘缓存得到位图文件
489      * @param uri
490      * @param config
491      * @return
492      */
493     public Bitmap getBitmapFromMemCache(String uri, BitmapDisplayConfig config) {
494         if (config == null) {
495             config = defaultDisplayConfig;
496         }
497         return globalConfig.getBitmapCache().getBitmapFromMemCache(uri, config);
498     }
499 
500     ////////////////////////////////////////// tasks  任务//////////////////////////////////////////////////////////////////////
501 
502     /**
503      * 支持暂停
504      */
505     @Override
506     public boolean supportPause() {
507         return true;
508     }
509 
510     /**
511      * 支持重新开始
512      */
513     @Override
514     public boolean supportResume() {
515         return true;
516     }
517 
518     /**
519      * 支持取消
520      */
521     @Override
522     public boolean supportCancel() {
523         return true;
524     }
525 
526     /**
527      * 暂停
528      */
529     @Override
530     public void pause() {
531         pauseTask = true;
532         flushCache();
533     }
534 
535     /**
536      * 刷新
537      */
538     @Override
539     public void resume() {
540         pauseTask = false;
541         synchronized (pauseTaskLock) {
542             pauseTaskLock.notifyAll();
543         }
544     }
545 
546     /**
547      * 取消
548      */
549     @Override
550     public void cancel() {
551         pauseTask = true;
552         cancelAllTask = true;
553         synchronized (pauseTaskLock) {
554             pauseTaskLock.notifyAll();
555         }
556     }
557 
558     /**
559      * 是否暂停
560      */
561     @Override
562     public boolean isPaused() {
563         return pauseTask;
564     }
565 
566     /**
567      * 是否是取消了
568      */
569     @Override
570     public boolean isCancelled() {
571         return cancelAllTask;
572     }
573 
574     ////////////////////////////////////////////////下面这些方法是否没有提供给开发者使用的///////////////////////////////////////////////////////////////
575 
576     @SuppressWarnings("unchecked")
577     private static <T extends View> BitmapLoadTask<T> getBitmapTaskFromContainer(T container, BitmapLoadCallBack<T> callBack) {
578         if (container != null) {
579             final Drawable drawable = callBack.getDrawable(container);
580             if (drawable instanceof AsyncDrawable) {
581                 final AsyncDrawable<T> asyncDrawable = (AsyncDrawable<T>) drawable;
582                 return asyncDrawable.getBitmapWorkerTask();
583             }
584         }
585         return null;
586     }
587 
588     private static <T extends View> boolean bitmapLoadTaskExist(T container, String uri, BitmapLoadCallBack<T> callBack) {
589         final BitmapLoadTask<T> oldLoadTask = getBitmapTaskFromContainer(container, callBack);
590 
591         if (oldLoadTask != null) {
592             final String oldUrl = oldLoadTask.uri;
593             if (TextUtils.isEmpty(oldUrl) || !oldUrl.equals(uri)) {
594                 oldLoadTask.cancel(true);
595             } else {
596                 return true;
597             }
598         }
599         return false;
600     }
601 
602     public class BitmapLoadTask<T extends View> extends PriorityAsyncTask<Object, Object, Bitmap> {
603         private final String uri;
604         private final WeakReference<T> containerReference;
605         private final BitmapLoadCallBack<T> callBack;
606         private final BitmapDisplayConfig displayConfig;
607 
608         private BitmapLoadFrom from = BitmapLoadFrom.DISK_CACHE;
609 
610         public BitmapLoadTask(T container, String uri, BitmapDisplayConfig config, BitmapLoadCallBack<T> callBack) {
611             if (container == null || uri == null || config == null || callBack == null) {
612                 throw new IllegalArgumentException("args may not be null");
613             }
614 
615             this.containerReference = new WeakReference<T>(container);
616             this.callBack = callBack;
617             this.uri = uri;
618             this.displayConfig = config;
619         }
620 
621         @Override
622         protected Bitmap doInBackground(Object... params) {
623 
624             synchronized (pauseTaskLock) {
625                 while (pauseTask && !this.isCancelled()) {
626                     try {
627                         pauseTaskLock.wait();
628                         if (cancelAllTask) {
629                             return null;
630                         }
631                     } catch (Throwable e) {
632                     }
633                 }
634             }
635 
636             Bitmap bitmap = null;
637 
638             // get cache from disk cache
639             if (!this.isCancelled() && this.getTargetContainer() != null) {
640                 this.publishProgress(PROGRESS_LOAD_STARTED);
641                 bitmap = globalConfig.getBitmapCache().getBitmapFromDiskCache(uri, displayConfig);
642             }
643 
644             // download image
645             if (bitmap == null && !this.isCancelled() && this.getTargetContainer() != null) {
646                 bitmap = globalConfig.getBitmapCache().downloadBitmap(uri, displayConfig, this);
647                 from = BitmapLoadFrom.URI;
648             }
649 
650             return bitmap;
651         }
652 
653         public void updateProgress(long total, long current) {
654             this.publishProgress(PROGRESS_LOADING, total, current);
655         }
656 
657         private static final int PROGRESS_LOAD_STARTED = 0;
658         private static final int PROGRESS_LOADING = 1;
659 
660         @Override
661         protected void onProgressUpdate(Object... values) {
662             if (values == null || values.length == 0) return;
663 
664             final T container = this.getTargetContainer();
665             if (container == null) return;
666 
667             switch ((Integer) values[0]) {
668                 case PROGRESS_LOAD_STARTED:
669                     callBack.onLoadStarted(container, uri, displayConfig);
670                     break;
671                 case PROGRESS_LOADING:
672                     if (values.length != 3) return;
673                     callBack.onLoading(container, uri, displayConfig, (Long) values[1], (Long) values[2]);
674                     break;
675                 default:
676                     break;
677             }
678         }
679 
680         @Override
681         protected void onPostExecute(Bitmap bitmap) {
682             final T container = this.getTargetContainer();
683             if (container != null) {
684                 if (bitmap != null) {
685                     callBack.onLoadCompleted(
686                             container,
687                             this.uri,
688                             bitmap,
689                             displayConfig,
690                             from);
691                 } else {
692                     callBack.onLoadFailed(
693                             container,
694                             this.uri,
695                             displayConfig.getLoadFailedDrawable());
696                 }
697             }
698         }
699 
700         @Override
701         protected void onCancelled(Bitmap bitmap) {
702             synchronized (pauseTaskLock) {
703                 pauseTaskLock.notifyAll();
704             }
705         }
706 
707         public T getTargetContainer() {
708             final T container = containerReference.get();
709             final BitmapLoadTask<T> bitmapWorkerTask = getBitmapTaskFromContainer(container, callBack);
710 
711             if (this == bitmapWorkerTask) {
712                 return container;
713             }
714 
715             return null;
716         }
717     }
718 }

3. BitmapUtils使用:

(1)新建一个Android工程,如下:

(2)首先我们来到主布局文件,如下:

activity_main.xml:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     tools:context="com.himi.bitmaputils.MainActivity" >
 7 
 8     <ListView
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent"
11         android:id="@+id/lv" />
12 
13 </LinearLayout>

item.xml:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="wrap_content"
 4     android:layout_height="wrap_content"
 5     android:orientation="horizontal" >
 6     <ImageView 
 7         android:src="@drawable/ic_launcher"
 8         android:layout_width="50dp"
 9         android:layout_height="50dp"
10         android:layout_margin="10dp"
11         android:id="@+id/iv"/>
12         
13     <TextView 
14         android:text="默认"
15         android:id="@+id/tv"
16         android:textSize="15sp"
17         android:layout_marginTop="25dp"
18         android:layout_marginLeft="80dp"
19         android:layout_width="wrap_content"
20         android:layout_height="wrap_content"/>
21     
22     
23 
24 </LinearLayout>

(3)这里上面我们使用到了ListView,那么就需要使用Adapter,这里我们需要自定义Adapter,如下:

 在新建的包"com.himi.bitmaputils.adapter"下,新建一个MyAdapter,如下:

  1 package com.himi.bitmaputils.adapter;
  2 
  3 
  4 import com.himi.bitmaputils.R;
  5 import com.lidroid.xutils.BitmapUtils;
  6 
  7 import android.content.Context;
  8 import android.graphics.Bitmap;
  9 import android.graphics.drawable.AnimationDrawable;
 10 import android.view.View;
 11 import android.view.ViewGroup;
 12 import android.widget.BaseAdapter;
 13 import android.widget.ImageView;
 14 import android.widget.TextView;
 15 
 16 public class MyAdapter extends BaseAdapter {
 17     
 18     public String[] Txt =  {
 19             "Angelababy",
 20             "刘德华",
 21             "张国荣",
 22             "朱珠"
 23             
 24         };
 25     
 26     public String[] Urls = {
 27             "http://49.123.72.28:8080/imgs/Angelababy.jpg",
 28             "http://49.123.72.28:8080/imgs/liudehua.jpg",
 29             "http://49.123.72.28:8080/imgs/zhangguorong.jpg",
 30             "http://49.123.72.28:8080/imgs/zhuzhu.jpg"
 31     };
 32     private Context context;
 33     
 34     private ViewHolder holder;
 35     
 36     public MyAdapter(Context context) {
 37         this.context = context;
 38     }
 39 
 40     @Override
 41     public int getCount() {
 42         // TODO Auto-generated method stub
 43         return Txt.length;
 44     }
 45 
 46     @Override
 47     public Object getItem(int position) {
 48         // TODO Auto-generated method stub
 49         return Txt[position];
 50     }
 51 
 52     @Override
 53     public long getItemId(int position) {
 54         // TODO Auto-generated method stub
 55         return position;
 56     }
 57 
 58     @Override
 59     public View getView(int position, View convertView, ViewGroup parent) {
 60         if(convertView ==null) {
 61             convertView = View.inflate(context, R.layout.item, null);
 62             
 63             holder = new ViewHolder();
 64             holder.iv = (ImageView) convertView.findViewById(R.id.iv);
 65             holder.tv = (TextView) convertView.findViewById(R.id.tv);
 66             
 67             convertView.setTag(holder);
 68             
 69             
 70         } else {
 71             holder = (ViewHolder) convertView.getTag();
 72         }
 73         /**
 74          * 加载assets中的图片(路径以assets开头)
 75          * 完整路径是:assets/img01.jpg
 76          */
 77         /*BitmapUtils util = new BitmapUtils(context);
 78         util.display(holder.iv, "assets/img0"+(position+1)+".jpg");
 79         
 80         holder.tv.setText(Txt[position]);*/
 81         
 82         
 83         /**
 84          *  加载本地图片(路径以/开头, 绝对路径)
 85          *    bitmapUtils.display(testImageView, "/sdcard/test.jpg");
 86          *  同上
 87          */
 88         
 89         
 90         /**
 91          * 加载网络图片
 92          */
 93         BitmapUtils util = new BitmapUtils(context,"/data/data/files/imgs");
 94         AnimationDrawable animation;
 95         
 96         holder.iv.setBackgroundResource(R.drawable.git);
 97         animation = (AnimationDrawable) holder.iv.getBackground();
 98         
 99         //设置加载图片过程中的动画gif
100         util.configDefaultLoadingImage(animation);
101         //设置加载失败默认图片
102         util.configDefaultLoadFailedImage(R.drawable.failed);
103         //配置图片参数
104         util.configDefaultBitmapConfig(Bitmap.Config.RGB_565);
105         //加载特定网络路径的图片
106         util.display(holder.iv, Urls[position]);
107         
108         holder.tv.setText(Txt[position]);
109         
110         return convertView;
111     }
112     
113     class ViewHolder {
114         ImageView iv;
115         TextView tv;
116     }
117     
118     
119 
120 }

  1)上面加载本地图片、assets目录图片比较简单,这里就不详细说明,上面有使用基本代码

  2)加载网络图片:

首先我们在Android工程中,添加网络权限;

1  <uses-permission android:name="android.permission.INTERNET"/>

接下来我们来模拟网络环境,我们开启Apache服务器,如下:

在相应apache服务器文件存放目录下,存放图片文件,如下:

同时上面配置了正在加载ing网络图片时候,加载中图片,使用到了Gif显示,关于Gif显示,可以参考如下笔记:

Android(java)学习笔记207:开源项目使用之gif view

或者

Android(java)学习笔记198:Android下的帧动画(Drawable Animation)

(4)来到MainActivity,如下:

 1 package com.himi.bitmaputils;
 2 
 3 import com.himi.bitmaputils.adapter.MyAdapter;
 4 
 5 import android.app.Activity;
 6 import android.os.Bundle;
 7 import android.widget.ListView;
 8 
 9 public class MainActivity extends Activity {
10     
11     private ListView lv;
12 
13     @Override
14     protected void onCreate(Bundle savedInstanceState) {
15         super.onCreate(savedInstanceState);
16         setContentView(R.layout.activity_main);
17         
18         lv = (ListView) findViewById(R.id.lv);
19         MyAdapter adapter = new MyAdapter(this);
20         
21         lv.setAdapter(adapter);
22         
23     }
24 
25     
26 }

(5)布署程序到模拟器上:

  • 正常情况下,如下:

  • 这里为了模拟场景,删除Apache服务器端liudehua.jpg图片资源,退出程序,重新继续运行,如下:

说明上面BitmapUtils内部自带了缓冲机制。

  • 这时候,卸载程序重新安装再次运行如下:

原文地址:https://www.cnblogs.com/hebao0514/p/5463146.html