Universal-Image-Loader加载网络图片
来源:互联网 发布:叉叉助手类似软件 编辑:程序博客网 时间:2024/06/16 16:39
一个简单的Listview,然后里面item就是一张图片,希望很流畅的加载网络图片,然后滑动的时候不会出现卡顿,也不会出现OOM现象。在断开网络连接的时候,点击listview的item,进入到图片详情界面,依旧能够加载出完整的图片。这里看一下效果图:
截屏的时候有点卡顿,第一张是有网络连接的时候加载的网络图片,第二张是断开网络连接时点击item,进入图片详情时加载的缓存图片。
这里用到的是Universal-Image-Loader,一个强大的图片加载框架,具有以下的特性:
1.多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
2.支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
3.支持图片的内存缓存,文件系统缓存或者SD卡缓存
4.支持图片下载过程的监听
5.根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
6.较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
7.提供在较慢的网络下对图片进行加载
界面布局很简单,就不贴代码了,具体看一下Universal-Image-Loader使用过程以及一些注意事项:
public class MyApplication extends Application { private MyApplication instance; @Override public void onCreate() { super.onCreate(); instance = this; initImageloader(); } public void initImageloader() { DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.ic_download) .showImageOnFail(R.drawable.ic_download) .resetViewBeforeLoading(false) // default .delayBeforeLoading(0).cacheInMemory(true) // default .cacheOnDisk(true) // default .considerExifParams(true) // default .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default .bitmapConfig(Bitmap.Config.ARGB_8888) // default .displayer(new SimpleBitmapDisplayer()) // default .handler(new Handler()) // default .build(); File picPath = new File(Environment.getExternalStorageDirectory() .getPath()+ File.separator+ "MyDemo"+ File.separator+ "files"); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder( getApplicationContext()) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions .diskCacheExtraOptions(480, 800, null) .threadPoolSize(3) // default .threadPriority(Thread.NORM_PRIORITY - 1) // default .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) .memoryCacheSize(2 * 1024 * 1024) .memoryCacheSizePercentage(13) // default .diskCache(new UnlimitedDiskCache(picPath)) // default .diskCacheSize(50 * 1024 * 1024) .diskCacheFileCount(1000) .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default .imageDownloader( new BaseImageDownloader(getApplicationContext())) // default .imageDecoder(new BaseImageDecoder(true)) // default .defaultDisplayImageOptions(options) // default .writeDebugLogs().build(); ImageLoader.getInstance().init(config); }}
新建一个MyApplication继承Application,Application是单例 (singleton)模式的一个类。且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些数据传递,数据共享等数据缓存等操作。在这里我们来创建图片加载器ImageLoader的配置参数。
ImageLoaderConfiguration使用了建造者模式配置参数,设置了线程池中线程个数,内存存储大小,数量,硬盘存储大小,数量等参数。
最后调用ImageLoader.getInstance().init(config)将设置参数传递进去,这里用的是单例模式–懒汉式双重校验锁
参考资料:
http://blog.csdn.net/dmk877/article/details/50311791
DisplayImageOptions用来配置图片显示的选项,比如图片在加载中ImageView显示的图片,加载失败显示的图片,是否需要使用内存缓存,是否需要使用文件缓存等等。这里都设置true,就不用每次都从网络上加载图片。
看一下适配器代码:
public class ImgListAdapter extends BaseAdapter { class ViewHolder { @ViewInject(R.id.web_img) public ImageView webImg; } private Context context; private LayoutInflater layoutinflater; private String[] imageUrls; public ImgListAdapter(String[] urls, Context context) { this.context = context; this.imageUrls = urls; this.layoutinflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return imageUrls.length; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int id) { // TODO Auto-generated method stub return id; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = layoutinflater.inflate(R.layout.img_item, null); viewHolder = new ViewHolder(); ViewUtils.inject(viewHolder, convertView); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } // 通过ImageLoader来获取网络图片 ImageLoader.getInstance().displayImage(imageUrls[position], viewHolder.webImg); return convertView; }}
通过ViewHolder来优化listview,通过ImageLoader的异步加载图片,只需要传进去两个参数,第一个是图片url,第二个是ImageView控件,ImageLoader会自动给我们缓存图片的,如果之前加载过了是不会再次下载图片,直接加载本地缓存好的图片。
接下来就是activity中的运用:
public class MainActivity extends Activity { ImgListAdapter adapter; ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview = (ListView) findViewById(R.id.listview); adapter = new ImgListAdapter(Images.imageThumbUrls, getApplicationContext()); listview.setAdapter(adapter); listview.setOnScrollListener(new PauseOnScrollListener(ImageLoader .getInstance(), false, true)); listview.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(getApplicationContext(), ImagePagerActivity.class); intent.putExtra("url", Images.imageThumbUrls[position]); startActivity(intent); } }); }}
其中需要注意的是:
listview.setOnScrollListener(new PauseOnScrollListener(ImageLoader .getInstance(), true, false));
Universal-Image-Loader提供了PauseOnScrollListener这个类来控制ListView,GridView滑动过程中停止去加载图片。第一个参数就是我们的图片加载对象ImageLoader, 第二个是控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了,第三个参数控制猛的滑动界面的时候图片是否加载。
给每个item设置了点击事件,传递当前item的URL到图片详情界面,这里我故意断开了网络连接,最后依旧能够得到缓存。看一下代码:
public class ImagePagerActivity extends Activity { ImageView pagerImg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image_pager); pagerImg = (ImageView) findViewById(R.id.pager_img); Intent intent = getIntent(); Bundle data = intent.getExtras(); ImageLoader.getInstance().displayImage((String) data.get("url"), pagerImg); }}
拿到上一个界面传递过来的URL,调用的还是displayImage((String) data.get(“url”)这个方法,只不过这次拿的是缓存,不再是从网络上下载的。
可以看到缓存都在自己定义的文件夹下面。
缓存策略的流程就是:
每次加载图片的时候都优先去内存缓存当中读取,当读取不到的时候则回去硬盘缓存中读取,而如果硬盘缓存仍然读取不到的话,就从网络上请求原始数据。
参考博客:
http://blog.csdn.net/xiaanming/article/details/26810303
http://blog.csdn.net/xiaanming/article/details/27525741
http://blog.csdn.net/xiaanming/article/details/39057201
- universal-image-Loader网络图片加载框架
- Universal-Image-Loader加载网络图片
- 网络图片加载Image-Universal-Loader
- Android网络图片加载_Android-Universal-Image-Loader
- 使用Android-Universal-Image-Loader加载网络图片
- 异步加载网络图片之Universal-Image-Loader的使用
- Universal-Image-Loader网络图片加载处理框架
- 使用universal-image-loader-1.9.3.jar加载网络图片
- Android-Universal-Image-Loader 异步加载图片
- 使用Android-Universal-Image-Loader加载图片
- Universal-Image-Loader加载listView中图片
- Android-Universal-Image-Loader加载图片
- universal-image-loader图片异步加载
- Android-Universal-Image-Loader 图片加载库
- Universal-Image-Loader异步加载图片详解
- Universal Image Loader 学习笔记-图片加载
- 使用Universal-Image-Loader加载图片
- 使用Universal-Image-Loader框架加载图片
- stm32 GPIO 操作例程
- linux sed命令详解
- 黑马程序员——Java---io流--文本文件读取写入的实现
- 【郑轻】[1762]Dml‘s secret
- html学习第一天
- Universal-Image-Loader加载网络图片
- 线程---Thread
- C# 过滤空格、换行、script、style等等标签
- swift-基础08-隐式解析,隐式装包,强制装包和断言
- PHP实现mysql事务处理
- 一起talk C栗子吧(第七十九回:C语言实例--父进程与子进程)
- 正则表达式基本语法
- 谷歌浏览器使用
- 安卓天气应用