zoukankan      html  css  js  c++  java
  • Android-Universal-Image-Loader使用介绍

    简介

    Android上最让人头疼的莫过于从网络获取图片、显示、回收,任何一个环节有问题都可能直接OOM,这个项目或许能帮到你。Universal Image Loader for Android的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载。它最初来源于Fedor Vlasov的项目,且自此之后,经过大规模的重构和改进

     

    imageloader 加载图片的一般流程是先判断内存中是否有对应的Bitmap,再判断磁盘(disk)中是否有,如果没有就从网络中加载。最后根据原先在UIL中的配置判断是否需要缓存Bitmap到内存或磁盘中。Bitmap加载完后,就对它进行解析,然后显示到特定的ImageView中,

     

    加载过程分析简图:


    使用imageLoader可以实现

    1. 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
    2. 支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
    3. 支持图片的内存缓存,文件系统缓存或者SD卡缓存
    4. 支持图片下载过程的监听
    5. 根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
    6. 较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
    7. 提供在较慢的网络下对图片进行加载

    初始化imageloader

    方式一:

    1. //创建默认的ImageLoader配置参数      
    2. ImageLoaderConfiguration configuration = ImageLoaderConfiguration      
    3.         .createDefault(this);      
    4. //Initialize ImageLoader with configuration.      
    5. ImageLoader.getInstance().init(configuration);   

    方式二:

    1. File cacheDir =getExternalStoragePath()+imageloader/Cache");  //获取自定义缓存路径  
    2. ImageLoaderConfigurationconfig = new ImageLoaderConfiguration     
    3.           .Builder(this)     
    4.           .memoryCacheExtraOptions(480, 800) // maxwidth, max height,即保存的每个缓存文件的最大长宽     
    5.           .threadPoolSize(3)//线程池内加载的数量     
    6.           .threadPriority(Thread.NORM_PRIORITY -2)     
    7.           .denyCacheImageMultipleSizesInMemory()     
    8.            .memoryCache(new UsingFreqLimitedMemoryCache(2* 1024 * 1024)) // You can pass your own memory cache implementation/你可以通过自己的内存缓存实现     
    9.            .memoryCacheSize(2 * 1024 * 1024)       
    10.           .discCacheSize(50 * 1024 * 1024)       
    11.           .discCacheFileNameGenerator(newMd5FileNameGenerator())//将保存的时候的URI名称用MD5 加密     
    12.            .tasksProcessingOrder(QueueProcessingType.LIFO)     
    13.            .discCacheFileCount(100) //缓存的文件数量     
    14.            .discCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径   ,这里是缓存到sd卡上   
    15.            .defaultDisplayImageOptions(DisplayImageOptions.createSimple())     
    16.            .imageDownloader(new BaseImageDownloader(this,5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间     
    17.            .writeDebugLogs() // Remove for releaseapp     
    18.           .build();//开始构建     
    19. ImageLoader.getInstance().init(config);    
    1. // 获取SD卡路径  
    2.     public  String getExternalStoragePath() {  
    3.         // 获取SdCard状态  
    4.         String state = android.os.Environment.getExternalStorageState();  
    5.   
    6.         // 判断SdCard是否存在并且是可用的  
    7.   
    8.         if (android.os.Environment.MEDIA_MOUNTED.equals(state)) {  
    9.   
    10.             if (android.os.Environment.getExternalStorageDirectory().canWrite()) {  
    11.   
    12.                 return android.os.Environment.getExternalStorageDirectory()  
    13.                         .getPath();  
    14.             }  
    15.         }  
    16.         return null;  
    17.   
    18.     }  



    方式三:

    1. // 获取最大内存  
    2.         int maxMemorySize = (int) (Runtime.getRuntime().maxMemory());  
    3.   
    4.         ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(  
    5.                 context);  
    6.         config.threadPriority(Thread.NORM_PRIORITY - 2);  
    7.         config.denyCacheImageMultipleSizesInMemory();// 不会在内存中缓存多个大小的图片  
    8.         config.diskCacheFileNameGenerator(new Md5FileNameGenerator());// 为了保证图片名称唯一  
    9.         config.diskCacheSize(maxMemorySize / 10);// 内存缓存大小默认是:app可用内存的1/8,这里设为1/10  
    10.   
    11.         config.tasksProcessingOrder(QueueProcessingType.LIFO);  
    12.         config.writeDebugLogs(); // Remove for release app  
    13.   
    14.         // Initialize ImageLoader with configuration.  
    15.         ImageLoader.getInstance().init(config.build());  


    最好是使用用方式三,这里是动态获取内存的大小 ,可以有效的避免一些内存溢出的效果  。。。。

    当然要将图片缓存到本地自定义的路径中,可以使用用方式二与方式三相结合使用    

    特别说明:

    1、ImageLoaderConfiguration 配置中的.discCacheFileNameGenerator()方法是将缓存下来的文件以什么方式命名

              里面可以调用的方法有  1.new Md5FileNameGenerator() //使用MD5对UIL进行加密命名

                             2.new HashCodeFileNameGenerator()//使用HASHCODE对UIL进行加密命名

    使用中的图像操作

    配制一 
    1. DisplayImageOptions options = new DisplayImageOptions.Builder()    
    2.           .showImageOnLoading(R.drawable.ic_stub)            //加载图片时的图片    
    3.           .showImageForEmptyUri(R.drawable.ic_empty)         //没有图片资源时的默认图片    
    4.           .showImageOnFail(R.drawable.ic_error)              //加载失败时的图片    
    5.           .cacheInMemory(true)                               //启用内存缓存    
    6.           .cacheOnDisk(true)                                 //启用外存缓存    
    7.           .considerExifParams(true)                          //启用EXIF和JPEG图像格式    
    8.           .displayer(new RoundedBitmapDisplayer(20))         //设置显示风格这里是圆角矩形    
    9.           .build();   

    配制二:

    1. DisplayImageOptions options = new DisplayImageOptions.Builder()    
    2.                           .showImageOnLoading(R.drawable.ic_launcher) //设置图片在下载期间显示的图片    
    3.                           .showImageForEmptyUri(R.drawable.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片    
    4.                           .showImageOnFail(R.drawable.ic_launcher)  //设置图片加载/解码过程中错误时候显示的图片  
    5.                           .cacheInMemory(true)//设置下载的图片是否缓存在内存中    
    6.                           .cacheOnDisc(true)//设置下载的图片是否缓存在SD卡中    
    7.                           .considerExifParams(true)  //是否考虑JPEG图像EXIF参数(旋转,翻转)  
    8.                           .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示    
    9.                           .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型//    
    10.                           .decodingOptions(android.graphics.BitmapFactory.Options decodingOptions)//设置图片的解码配置    
    11.                           //.delayBeforeLoading(int delayInMillis)//int delayInMillis为你设置的下载前的延迟时间  
    12. //设置图片加入缓存前,对bitmap进行设置    
    13.                          //.preProcessor(BitmapProcessor preProcessor)    
    14.                           .resetViewBeforeLoading(true)//设置图片在下载前是否重置,复位    
    15.                            .displayer(new RoundedBitmapDisplayer(20))//是否设置为圆角,弧度为多少    
    16.                           .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间    
    17.                            .build();//构建完成    

     

     

    特别说明:

       1、imageScaleType(ImageScaleType imageScaleType) 是设置 图片的缩放方式
         缩放类型mageScaleType:

                  EXACTLY :图像将完全按比例缩小的目标大小
                  EXACTLY_STRETCHED:图片会缩放到目标大小完全
                  IN_SAMPLE_INT:图像将被二次采样的整数倍
                  IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
                  NONE:图片不会调整
      2、.displayer(BitmapDisplayer displayer)   是设置 图片的显示方式
          显示方式displayer
                 RoundedBitmapDisplayerint roundPixels)设置圆角图片
                 FakeBitmapDisplayer()这个类什么都没做
                 FadeInBitmapDisplayerint durationMillis)设置图片渐显的时间
    SimpleBitmapDisplayer()正常显示一张图片

    加载中使用的地址

    1. String imageUri = "http://site.com/image.png"; // 网络图片    
    2. String imageUri = "file:///mnt/sdcard/image.png"; //SD卡图片    
    3. String imageUri = "content://media/external/audio/albumart/13"; // 媒体文件夹    
    4. String imageUri = "assets://image.png"; // assets    
    5. String imageUri = "drawable://" + R.drawable.image; //  drawable文件    


    1. "http://site.com/image.png" // from Web  
    2. "file:///mnt/sdcard/image.png" // from SD card  
    3. "file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)  
    4. "content://media/external/images/media/13" // from content provider  
    5. "content://media/external/video/media/13" // from content provider (video thumbnail)  
    6. "assets://image.png" // from assets  
    7. "drawable://" + R.drawable.img // from drawables (non-9patch images)  



     

    设置显示图片

    displayImage方法

    可以根据需要使用不同的构造

    1. 1、ImageLoader.getInstance().displayImage(uri, imageView);  
    2. 2、  ImageLoader.getInstance().displayImage(uri, imageView, options);  
    3. 3、  ImageLoader.getInstance().displayImage(uri, imageView, listener);  
    4. 4、  ImageLoader.getInstance().displayImage(uri, imageView, options, listener);  
    5. 5、  ImageLoader.getInstance().displayImage(uri, imageView, options, listener, progressListener);  
    1. imageUrl   图片的URL地址  
    2. imageView  显示图片的ImageView控件    
    3. options    DisplayImageOptions配置信息   
    4. listener   图片下载情况的监听  
    5. progressListener  图片下载进度的监听  

    loadImage方法

    并常用的加载方法:

    1. ImageView mImageView = (ImageView) findViewById(R.id.image);    
    2.         String imageUrl = "";    
    3.   
    4.         ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener(){    
    5.     
    6.             @Override    
    7.             public void onLoadingComplete(String imageUri, View view,    
    8.                     Bitmap loadedImage) {    
    9.                 super.onLoadingComplete(imageUri, view, loadedImage);    
    10.                 mImageView.setImageBitmap(loadedImage);    
    11.             }    
    12.                 
    13.         });    

    初始化一个图片显示大小 

    1. ImageView mImageView = (ImageView) findViewById(R.id.image);    
    2.        String imageUrl = "";    
    3.            
    4.        ImageSize mImageSize = new ImageSize(100, 100);    
    5.            
    6.        ImageLoader.getInstance().loadImage(imageUrl, mImageSize, new SimpleImageLoadingListener(){    
    7.    
    8.            @Override    
    9.            public void onLoadingComplete(String imageUri, View view,    
    10.                    Bitmap loadedImage) {    
    11.                super.onLoadingComplete(imageUri, view, loadedImage);    
    12.                mImageView.setImageBitmap(loadedImage);    
    13.            }    
    14.                
    15.        });    



    设置options参数加载 

    1. ImageView mImageView = (ImageView) findViewById(R.id.image);    
    2.         String imageUrl = "";    
    3.         ImageSize mImageSize = new ImageSize(100, 100);  //设置图片显示大小 为100 X 100  
    4.             
    5.         //显示图片的配置    
    6.         DisplayImageOptions options = new DisplayImageOptions.Builder()    
    7.                 .cacheInMemory(true)    
    8.                 .cacheOnDisk(true)    
    9.                 .bitmapConfig(Bitmap.Config.RGB_565)    
    10.                 .build();    
    11.             
    12.         ImageLoader.getInstance().loadImage(imageUrl, mImageSize, options, new SimpleImageLoadingListener(){    
    13.     
    14.             @Override    
    15.             public void onLoadingComplete(String imageUri, View view,    
    16.                     Bitmap loadedImage) {    
    17.                 super.onLoadingComplete(imageUri, view, loadedImage);    
    18.                 mImageView.setImageBitmap(loadedImage);    
    19.             }    
    20.                 
    21.         });    





    加载图片的监听

    1. imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {    
    2.     @Override    
    3.     public void onLoadingStarted() {    
    4.        //开始加载的时候执行    
    5.     }    
    6.     @Override    
    7.     public void onLoadingFailed(FailReason failReason) {          
    8.        //加载失败的时候执行    
    9.     }     
    10.     @Override     
    11.     public void onLoadingComplete(Bitmap loadedImage) {    
    12.        //加载成功的时候执行    
    13.     }     
    14.     @Override     
    15.     public void onLoadingCancelled() {    
    16.        //加载取消的时候执行    
    17.     
    18.     }});   


    特别说明 

      在图片加载成功之后(onlaodingComplete()方法中),可以对获取到的Bitmap进行各种大小设置,图形裁剪操作以及动画效果添加等,最后再加图片展示到控件上


    1. /**  
    2.    * 图片加载第一次显示监听器  
    3.    * @author Administrator  
    4.    *  
    5.    */    
    6.   private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {    
    7.           
    8.       static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());    
    9.   
    10.       @Override    
    11.       public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {    
    12.           if (loadedImage != null) {    
    13.               ImageView imageView = (ImageView) view;    
    14.               // 是否第一次显示    
    15.               boolean firstDisplay = !displayedImages.contains(imageUri);    
    16.               if (firstDisplay) {    
    17.                   // 图片淡入效果    
    18.                   FadeInBitmapDisplayer.animate(imageView, 500);    
    19.                   displayedImages.add(imageUri);    
    20.               }    
    21.           }    
    22.       }       @Override    
    23.               public void onLoadingStarted(String imageUri, View view) {    
    24.                   spinner.setVisibility(View.VISIBLE);    
    25.               }    
    26.   
    27.               @Override    
    28.               public void onLoadingFailed(String imageUri, View view, FailReason failReason) {    
    29.                   String message = null;    
    30.                   switch (failReason.getType()) {  // 获取图片失败类型    
    31.                       case IO_ERROR:              // 文件I/O错误    
    32.                           message = "Input/Output error";    
    33.                           break;    
    34.                       case DECODING_ERROR:        // 解码错误    
    35.                           message = "Image can't be decoded";    
    36.                           break;    
    37.                       case NETWORK_DENIED:        // 网络延迟    
    38.                           message = "Downloads are denied";    
    39.                           break;    
    40.                       case OUT_OF_MEMORY:         // 内存不足    
    41.                           message = "Out Of Memory error";    
    42.                           break;    
    43.                       case UNKNOWN:               // 原因不明    
    44.                           message = "Unknown error";    
    45.                           break;    
    46.                   }    
    47.                   Toast.makeText(ImagePagerActivity.this, message, Toast.LENGTH_SHORT).show();    
    48.    
    49.               }    
    50.           }  

    }

    设置进度的方法

    1. imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {    
    2.     @Override    
    3.     public void onLoadingStarted() {    
    4.        //开始加载的时候执行    
    5.     }    
    6.     @Override    
    7.     public void onLoadingFailed(FailReason failReason) {          
    8.        //加载失败的时候执行    
    9.     }        
    10.     @Override        
    11.     public void onLoadingComplete(Bitmap loadedImage) {    
    12.        //加载成功的时候执行    
    13.     }        
    14.     @Override        
    15.     public void onLoadingCancelled() {    
    16.        //加载取消的时候执行    
    17.     },new ImageLoadingProgressListener() {          
    18.       @Override    
    19.       public void onProgressUpdate(String imageUri, View view, int current,int total) {       
    20.       //在这里更新 ProgressBar的进度信息    
    21.       }    
    22.     });   



    缓存的清理

    1. @Override    
    2. public void onDestroy() {    
    3.           super.onDestroy();    
    4.           imageLoader.clearMemoryCache();    
    5.           imageLoader.clearDiskCache();    
    6. }   
    1. // 获取占用最大内存  
    2.         maxMemory = (int) Runtime.getRuntime().maxMemory();  
    1.              if (maxMemory 40 * 1024 * 1024) {  
    2. ImageLoader.getInstance().clearMemoryCache();  
    3. ImageLoader.getInstance().clearDiskCache();  



    这里可以依据需求来设定,我这里采用的是检测 下内存,如果内存大小小于40M,那么在销毁的时候 ,清理缓存 ,这样处理可以有效的解决下加载图片过程中出现的内存溢出问题(例如 512M内存的手机)

    在ListView与GridView中滑动过程中停止加载图片

    1. listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));      
    2. gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));  


    第一个参数就是我们的图片加载对象ImageLoader, 第二个是控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了,第三个参数控制猛的滑动界面的时候图片是否加载

    补充说明 

    如果经常出现OOM(别人那边看到的,觉得很有提的必要)
       ①减少配置之中线程池的大小,(.threadPoolSize).推荐1-5;
       ②使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
       ③使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者.imageScaleType(ImageScaleType.EXACTLY);
       ④避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象;
       ⑤使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();


     Android自定义控件ImageViwe(一)——依据控件的大小来设置缩放图片显示
        点击打开链接
        
     Android自定义ImageView(二)——实现双击放大与缩小图片
        点击打开链接
        
     Android自定义控件ImageViwe(三)——随手指进行图片的缩放
       点击打开链接
        
     Android自定义控件ImageViwe(四)——多点触控实现图片的自由移动  
        点击打开链接
        
     Android ListView分组排序显示数据
        点击打开链接
        
     Android自定义下拉刷新功能的ListView
       点击打开链接
        
     Android音乐播放器高级开发
        点击打开链接
        
     Android自定义控件之流式布局
     点击打开链接

  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/9232578.html
Copyright © 2011-2022 走看看