Android图片异步加载之Android-Universal-Image-Loader使用1

  •    Android开发中我们会经常遇到图片过多或操作不当造成OOM异常,有时虽然是解决了这个问题但却会影响程序的运行效率,例如:当用户在快速滑动滚动条的过程中,我们程序在仍在艰难的加载服务器端的图片,这样给用户造成了极不好的体验。其实网络上关于图片的异步加载和缓存的讲解很多,但是其实,写一个这方面的程序还是比较麻烦的,要考虑多线程,缓存,内存溢出等很多方面,针对这一光大开发者都会遇到的问题,一些牛人们已经帮我们解决了这一问题,今天我为大家介绍一款很流行的开源类库,可以很很好的解决大家的烦恼!

       

    一.介绍:

       Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。

       在GitHub上面的一个开源类库(官方下载:https://github.com/nostra13/Android-Universal-Image-Loader)

     

      特点:

           1.多线程的图像加载;

           2.图片异步加载缓存机制,包括内存缓存(软引用)及本地缓存;

           3.动态对ImageLoader的配置(线程池的大小,HTTP选项,内存和光盘高速缓存方式,显示图像,以及其他选项);

           4.对加载过程实现监听和事件处理;

           5.能够配置加载图片的显示选项,包括图片圆角处理和加载完成显示动画等;

    (官方截图)
     

    \
     

    二.使用

      1.将下载下来的zip包,解压开得到如下图所示文件夹
     

    \
     

      2.将universal-image-loader-1.8.6-with-sources.jar导入到新建的项目中,参考sample中的例子进行使用即可。为了让新手们快速掌握这里我简单讲解一下它的使用过程(使用该类库中ImageLoader加载图片,ListView、GridView、ViewPager)

    Demo项目图解:
     

    \
     

    2.1.在程序启动时,用户可以根据自己的情况初始化ImageLoaderConfiguration

     

    public class MyApplication extends Application{ 
        @Override 
        public void onCreate() { 
            super.onCreate(); 
            initImageLoader(getApplicationContext()); 
        } 
        /**初始化图片加载类配置信息**/
        public static void initImageLoader(Context context) { 
            // This configuration tuning is custom. You can tune every option, you may tune some of them, 
            // or you can create default configuration by 
            //  ImageLoaderConfiguration.createDefault(this); 
            // method. 
            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) 
                .threadPriority(Thread.NORM_PRIORITY - 2)//加载图片的线程数 
                .denyCacheImageMultipleSizesInMemory() //解码图像的大尺寸将在内存中缓存先前解码图像的小尺寸。 
                .discCacheFileNameGenerator(new Md5FileNameGenerator())//设置磁盘缓存文件名称 
                .tasksProcessingOrder(QueueProcessingType.LIFO)//设置加载显示图片队列进程 
                .writeDebugLogs() // Remove for release app 
                .build(); 
            // Initialize ImageLoader with configuration. 
            ImageLoader.getInstance().init(config); 
        } 
    }



    别忘了在AndroidManifest.xml中

     

    android:name=".MyApplication"


    2.2.在MainActivity中我们做的仅仅是跳转到对应的界面,下面看一下ListView中的具体使用,剩下两个自己看一下Demo,原理一样。

    ImageListActivity:

     
    /** 
     * listView中使用ImageLoader 
     * @author ZHF 
     * 
     */
    public class ImageListActivity extends AbsListViewBaseActivity { 
        DisplayImageOptions options; //配置图片加载及显示选项 
        String[] imageUrls; 
        @Override
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.ac_image_list); 
            //获取url数组 
            Bundle bundle = getIntent().getExtras(); 
            imageUrls = bundle.getStringArray(Extra.IMAGES); 
            //配置图片加载及显示选项(还有一些其他的配置,查阅doc文档吧) 
            options = new DisplayImageOptions.Builder() 
                .showStubImage(R.drawable.ic_stub)    //在ImageView加载过程中显示图片 
                .showImageForEmptyUri(R.drawable.ic_empty)  //image连接地址为空时 
                .showImageOnFail(R.drawable.ic_error)  //image加载失败 
                .cacheInMemory(true)  //加载图片时会在内存中加载缓存 
                .cacheOnDisc(true)   //加载图片时会在磁盘中加载缓存 
                .displayer(new RoundedBitmapDisplayer(20))  //设置用户加载图片task(这里是圆角图片显示) 
                .build(); 
            listView = (ListView) findViewById(android.R.id.list); 
            //绑定适配器 
            listView.setAdapter(new ItemAdapter()); 
            listView.setOnItemClickListener(new OnItemClickListener() { 
                @Override
                public void onItemClick(AdapterView parent, View view, int position, long id) { 
                    startImagePagerActivity(position); 
                } 
            }); 
        } 
        @Override
        public void onBackPressed() { 
            AnimateFirstDisplayListener.displayedImages.clear(); 
            super.onBackPressed(); 
        } 
        private void startImagePagerActivity(int position) { 
            Intent intent = new Intent(this, ImagePagerActivity.class); 
            intent.putExtra(Extra.IMAGES, imageUrls); 
            intent.putExtra(Extra.IMAGE_POSITION, position); 
            startActivity(intent); 
        } 
        /**自定义图片适配器**/
        class ItemAdapter extends BaseAdapter { 
            private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener(); 
            private class ViewHolder { 
                public TextView text; 
                public ImageView image; 
            } 
            @Override
            public int getCount() { 
                return imageUrls.length; 
            } 
            @Override
            public Object getItem(int position) { 
                return position; 
            } 
            @Override
            public long getItemId(int position) { 
                return position; 
            } 
            @Override
            public View getView(final int position, View convertView, ViewGroup parent) { 
                View view = convertView; 
                final ViewHolder holder; 
                if (convertView == null) { 
                    view = getLayoutInflater().inflate(R.layout.item_list_image, parent, false); 
                    holder = new ViewHolder(); 
                    holder.text = (TextView) view.findViewById(R.id.text); 
                    holder.image = (ImageView) view.findViewById(R.id.image); 
                    view.setTag(holder); 
                } else { 
                    holder = (ViewHolder) view.getTag(); 
                } 
                holder.text.setText("Item " + (position + 1)); 
                //Adds display image task to execution pool. Image will be set to ImageView when it's turn. 
                imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener); 
                return view; 
            } 
        } 
        /**图片加载监听事件**/
        private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { 
            static final List displayedImages = Collections.synchronizedList(new LinkedList()); 
            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
                if (loadedImage != null) { 
                    ImageView imageView = (ImageView) view; 
                    boolean firstDisplay = !displayedImages.contains(imageUri); 
                    if (firstDisplay) { 
                        FadeInBitmapDisplayer.animate(imageView, 500); //设置image隐藏动画500ms 
                        displayedImages.add(imageUri); //将图片uri添加到集合中 
                    } 
                } 
            } 
        } 
    }


     

    说明:

       1.使用ImageLoader加载图片,只要在Adapter的getView方法中调用displayImage方法完成了异步列表图片加载,其中options是之前定义的图片加载和显示选项(我们这里使用的是RoundedBitmapDisplayer圆角图片显示),animateFirstListener是当图片第一次加载的监听事件,目的在于显示一个淡入的显示效果动画,可以添加其他事件

       2.进本人测试,官网例子中的Constant类中图片的Uri在手机中链接很慢,完全达不到效果,之后我将其更改为其他一系列图片的Uri,便于观察效果!

     

    效果图:
     

    \


     

      最后,大家在使用的时候记得关注一下在/sdcard/Android/data/[package_name]/cache目录下的缓存的文件。记得定期清理缓存,否则时间一长,SD卡就会被占满了,同时也可以在ImageLoaderConfiguration中配置SD的缓存策略,限制缓存文件数量(memoryCacheSizePercentage),限制缓存文件最大尺寸(memoryCacheSize)等选项。


     

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值