Android中Universal Image Loader开源框架的简单使用
UIL (Universal Image Loader)aims to provide a powerful, flexible and highly customizable instrument for image loading, caching and displaying. It provides a lot of configuration options and good control over the image loading and caching process.(不知道怎么介绍,先上一段英文吧,嘿嘿)
其实之前看过郭神的文章里讲了谷歌的Volley的一些简单使用(http://blog.csdn.net/guolin_blog/article/details/17482095),但不知为什么感觉用Universal-Image-Loader的人似乎比Volley的更多,于是便决定来认识认识Universal-Image-Loader。
Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。所以,如果你的程序里需要这个功能的话,那么不妨试试它。因为已经封装好了一些类和方法。我们 可以直接拿来用了。而不用重复去写了。其实,写一个这方面的程序还是比较麻烦的,要考虑多线程,缓存,内存溢出等很多方面。
这个开源库的特点:
- 多线程的图像加载
- ImageLoader对应的丰富的配置
- 图像可在内存或磁盘中缓存
- 为图片的个性化显示配置接口
- 监听加载过程
这个开源库还在不断的更新中,比如说UIL的新版(1.9.4)也快出来了。
简单描述一下这个项目的结构:每一个图片的加载和显示任务都运行在独立的线程中,除非这个图片缓存在内存中,这种情况下图片会立即显示。如果需要的图片缓存在本地,他们会开启一个独立的线程队列。如果在缓存中没有正确的图片,任务线程会从线程池中获取,因此,快速显示缓存图片时不会有明显的障碍。(别人那边借鉴的这段)
流程图:
使用方法:
Universal-Image-Loader的github的地址:https://github.com/nostra13/Android-Universal-Image-Loader
怎么下载就不说了吧,前面几篇博文中都说了在github上怎么下载的。开源库下载下来后解压,打开文件夹。有一个名称为“library”的文件夹,它就是开发需要的开源库。把“library”导入eclipse中并更名为“ImageLoderLibrary”(当然也可以不换名称,个人习惯)。
来做一个照片墙吧。
新建一个Android工程,命名为“zhj_ImageLoder”。
在清单文件中添加权限:
<!-- Include following permission if you load images from Internet -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Include following permission if you want to cache images on SD card -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Universal-Image-Loader要求在第一次使用ImageLoader之前要完成配置,因此决定在Application启动时就完成配置。
先新建一个类,名称为“MyApplication”,继承自Application。并在清单文件中替换掉默认的Application。
<application
android:name="com.topcsa.zhj_imageloder.MyApplication"
其详细代码如下:
public class MyApplication extends Application {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
this)
.memoryCacheExtraOptions(480, 800)
// 缓存在内存的图片的宽和高度
// default = device screen dimensions
.diskCacheExtraOptions(480, 800, null)
.threadPoolSize(3)
// 线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY - 2)
.tasksProcessingOrder(QueueProcessingType.FIFO)
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))//你可以通过自己的内存缓存实现
.memoryCacheSize(3 * 1024 * 1024)// 缓存到内存的最大数据
.memoryCacheSizePercentage(13)
.diskCacheSize(50 * 1024 * 1024)// //缓存到文件的最大数据
.diskCacheFileCount(100)// 文件数量
.diskCacheFileNameGenerator(new Md5FileNameGenerator())//将保存的时候的URI名称用MD5 加密
.imageDownloader(new BaseImageDownloader(this)) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.writeDebugLogs()// Remove for release app
.build();
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config);// 初始化
} }
其实并不是需要对所有的属性都进行设置,不过我个人觉得多认识一些相关属性总不至于太陌生。
接下来是布局文件activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <GridView
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="3"
android:padding="4dip"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip" /> </LinearLayout>
其次是item_grid_image.xml:(一个ImageView和ProgressBar)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dip"> <ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="120dip"
android:adjustViewBounds="true"
android:contentDescription="Image"
android:scaleType="centerCrop" /> <ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="100"
android:layout_gravity="bottom"
style="@style/ProgressBarStyle" />
</FrameLayout>
接着是图片连接的常量类:
public final class Constants { public static final String[] url = new String[] { "http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141193718588.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141209338554.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141221831290.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141234334937.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141246838674.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141257777597.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141271844948.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141284347684.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141298408763.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141323404047.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141335907784.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141357781081.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141370284628.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141381224641.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141395280001.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141407783738.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141428094222.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141443729035.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141476532255.jpg",
"http://10.10.9.100:2014/Back/PhotoManage/Images/photo140928111042693571/Thumbnail/image2014101415141490609616.jpg" }; public final static String[] imageThumbUrls = new String[] {
"http://img4.duitang.com/uploads/item/201302/08/20130208100902_ZGsLH.thumb.600_0.jpeg",
"http://cdn.duitang.com/uploads/item/201209/09/20120909183611_8zWYK.thumb.600_0.jpeg",
"http://img2.duitang.com/uploads/item/201207/10/20120710192155_XkiGA.thumb.600_0.jpeg",
"http://pic11.nipic.com/20101205/4948186_160603018432_2.jpg",
"http://img4.duitang.com/uploads/item/201302/08/20130208100856_52frh.thumb.600_0.jpeg",
"http://cdn.duitang.com/uploads/item/201302/08/20130208100951_szccZ.thumb.600_0.jpeg",
"http://pic.yesky.com/imagelist/08/51/10626239_2621.jpg",
"http://cdn.duitang.com/uploads/item/201307/02/20130702114230_HAEzN.jpeg",
"http://img4.duitang.com/uploads/item/201207/20/20120720121315_AMGBs.thumb.600_0.jpeg",
"http://img4.duitang.com/uploads/item/201208/18/20120818131445_iZyZr.jpeg",
"http://img4.duitang.com/uploads/item/201208/18/20120818131427_hmiH8.thumb.600_0.jpeg",
"http://img4.duitang.com/uploads/item/201208/18/20120818125423_sLXP3.thumb.600_0.jpeg",
"http://wenwen.sogou.com/p/20100623/20100623101110-601052657.jpg",
"http://img4.duitang.com/uploads/item/201303/07/20130307155548_YQ4XF.jpeg",
"http://img4.duitang.com/uploads/item/201207/10/20120710192328_SNKnn.thumb.600_0.jpeg",
"http://img5.duitang.com/uploads/item/201208/18/20120818125605_E4vKP.thumb.600_0.jpeg",
"http://cdn.duitang.com/uploads/item/201302/08/20130208100806_5QWNi.thumb.600_0.jpeg",
"http://img4.duitang.com/uploads/item/201208/18/20120818131205_QYTww.jpeg",
"http://img5.duitang.com/uploads/item/201208/09/20120809181114_GWCsa.thumb.600_0.jpeg",
"http://u2.tdimg.com/9/93/99/3142256775268338535609632489410975049.jpg",
"http://img4.duitang.com/uploads/item/201302/08/20130208100801_yFWWU.thumb.600_0.jpeg",
"http://img2.duitang.com/uploads/item/201302/08/20130208100848_AuXKR.thumb.600_0.jpeg",
"http://img4.duitang.com/uploads/blog/201403/19/20140319115139_vkLtG.thumb.600_0.jpeg",
"http://img5.duitang.com/uploads/item/201310/25/20131025225609_raPHx.thumb.700_0.jpeg",
"http://img4.duitang.com/uploads/item/201302/08/20130208100839_nrKnt.thumb.600_0.jpeg",
"http://c.hiphotos.baidu.com/zhidao/pic/item/f636afc379310a5509e3d5a1b54543a98326109b.jpg",
"http://img4.duitang.com/uploads/item/201305/04/20130504214309_yafH3.jpeg",
"http://picm.bbzhi.com/dongmanbizhi/saber/game_manwall_189706_m.jpg",
"http://img4.duitang.com/uploads/blog/201401/19/20140119201601_H52YL.thumb.600_0.jpeg",
"http://www.wszw.com/files_upload/forum/106/PF8.jpg",
"http://f.hiphotos.baidu.com/zhidao/pic/item/cb8065380cd79123e26154f9ad345982b3b780be.jpg",
"http://cdn.duitang.com/uploads/item/201207/16/20120716113231_TfxMs.jpeg",
"http://wenwen.sogou.com/p/20100227/20100227235017-1317494694.jpg",
"http://f.hiphotos.baidu.com/zhidao/pic/item/f9198618367adab4bfb537028bd4b31c8701e40e.jpg",
"http://x1.zhuti.com/down/2012/12/20-xp/jzqs-1.jpg",
"http://cdn.duitang.com/uploads/item/201208/30/20120830083246_URRF5.thumb.600_0.jpeg",
"http://imgstore.cdn.sogou.com/app/a/100540002/418617.jpg?f=download",
"http://img4.duitang.com/uploads/blog/201403/17/20140317100704_ixJ2B.jpeg",
"http://img5.duitang.com/uploads/item/201207/24/20120724192503_hACcr.jpeg",
"http://wenwen.sogou.com/p/20090613/20090613201954-1124405935.jpg" }; }
OK!
最后的最后,也是最重要的地方来了,在Activity中的具体实现。
首先我们还应该实现对图像的操作设置。
(其实这块应该可以也在Application中启动,不过没这么试过)
DisplayImageOptions options;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)// //默认图片
.showImageForEmptyUri(R.drawable.ic_empty)// url为空时展示的图片
.showImageOnFail(R.drawable.ic_error)// 图片加载失败时的图片
.cacheInMemory(true)// 缓存到内存
.cacheOnDisk(true)// 缓存到磁盘
.considerExifParams(true)// Sets whether ImageLoader will
// consider EXIF parameters of JPEG
// image (rotate, flip)
.displayer(new RoundedBitmapDisplayer(5))// 图片圆角显示
.bitmapConfig(Bitmap.Config.RGB_565).build();
好的,已经对ImageLoder和图片都进行了设置,最后也就是获取图片的方法了。
获取图像的方法一共有六个,三个比较简单,三个比较完整。如下:
Simple
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView);
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
// Load image, decode it to Bitmap and return Bitmap synchronously
Bitmap bmp = imageLoader.loadImageSync(imageUri);
Complete
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
...
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
...
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
...
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
...
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
...
}
});
// Load image, decode it to Bitmap and return Bitmap to callback
ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
imageLoader.loadImage(imageUri, targetSize, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
// Load image, decode it to Bitmap and return Bitmap synchronously
ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options);
Activity中完整的代码实现如下:(呃,写的有点乱哈,君莫笑……)
public class MainActivity extends Activity { DisplayImageOptions options;
String[] imageUrls = Constants.imageThumbUrls; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)// //默认图片
.showImageForEmptyUri(R.drawable.ic_empty)// url为空时展示的图片
.showImageOnFail(R.drawable.ic_error)// 图片加载失败时的图片
.cacheInMemory(true)// 缓存到内存
.cacheOnDisk(true)// 缓存到磁盘
.considerExifParams(true)// Sets whether ImageLoader will
// consider EXIF parameters of JPEG
// image (rotate, flip)
.displayer(new RoundedBitmapDisplayer(5))// 图片圆角显示
.bitmapConfig(Bitmap.Config.RGB_565).build(); GridView gv = (GridView) findViewById(R.id.gridview);
gv.setAdapter(new myAdapter()); } class myAdapter extends BaseAdapter {
private LayoutInflater inflater; myAdapter() {
inflater = LayoutInflater.from(MainActivity.this);
} @Override
public int getCount() {
// TODO Auto-generated method stub
return imageUrls.length;
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return imageUrls[position];
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_grid_image,
parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView
.findViewById(R.id.image);
holder.progressBar = (ProgressBar) convertView
.findViewById(R.id.progress);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Complete(完整的使用方法)
// 有简单的使用方法,这里未展示
ImageLoader.getInstance().displayImage(imageUrls[position],
holder.imageView, options,
new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
holder.progressBar.setProgress(0);
holder.progressBar.setVisibility(View.VISIBLE);
} @Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
holder.progressBar.setVisibility(View.GONE);
} @Override
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
holder.progressBar.setVisibility(View.GONE);
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri,
View view, int current, int total) {
holder.progressBar.setProgress(Math.round(100.0f
* current / total));
}
});
return convertView;
} } static class ViewHolder {
ImageView imageView;
ProgressBar progressBar;
} }
在此,照片墙的实现就做好了,赶快运行一下吧。如图:
(全是Saber,我女王啊~嘿嘿)
PS:
Acceptable URIs examples:
String imageUri = "http://site.com/image.png"; // from Web
String imageUri = "file:///mnt/sdcard/image.png"; // from SD card
String imageUri = "content://media/external/audio/albumart/1"; // from content provider
String imageUri = "assets://image.png"; // from assets
String imageUri = "drawable://" + R.drawable.img; // from drawables (non-9patch images)
NOTE: Use drawable://
only if you really need it! Always consider the native way to load drawables -ImageView.setImageResource(...)
instead of using of ImageLoader
DEMO下载:http://download.csdn.net/detail/af74776/8084109
Android中Universal Image Loader开源框架的简单使用的更多相关文章
- Android中常用的优秀开源框架
Android开源框架库分类,挑选出最常用,最实用的开源项目,本篇主要介绍的是优秀开源框架库和项目,UI个性化控件会独立介绍.UI个性化控件 Index Dependency Injections A ...
- Android酷炫有用的开源框架
一.代码库 1.from 代码家 整理比較好的源代码连接 一.兼容类库 ActionBarSherlock : Action Bar是Android 3.0后才開始支持的,ActionBarSher ...
- Android酷炫实用的开源框架(UI框架)
Android酷炫实用的开源框架(UI框架) 前言 忙碌的工作终于可以停息一段时间了,最近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮 ...
- Android酷炫实用的开源框架——UI框架(转)
转载别人整理好的文章,列出了很多炫酷的UI开源设计 原文地址:http://www.androidchina.net/1992.html 1.Side-Menu.Android分类侧滑菜单,Yalan ...
- Android酷炫实用的开源框架(UI框架) 转
Android酷炫实用的开源框架(UI框架) 前言 忙碌的工作终于可以停息一段时间了,最近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮 ...
- 黄聪:Android酷炫实用的开源框架(UI框架)(转)
Android酷炫实用的开源框架(UI框架) 前言 忙碌的工作终于可以停息一段时间了,最近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮 ...
- Android 学习笔记之Volley开源框架解析(一)
PS:看完了LGD的六场比赛...让人心酸... 学习内容: 1.Http请求的过程... 2.Volley的简单介绍... 1.Http请求... 这里只是简单的说一下Http请求的过程.. ...
- Android多媒体开发-- android中OpenMax的实现整体框架
1.android中用openmax来干啥? android中的AwesomePlayer就 是用openmax来做(code)编解码,其实在openmax接口设计中,他不光能用来当编解码.通过他的组 ...
- IT观察】网络通信、图片显示、数据库操作……Android程序员如何利用开源框架
每个Android 程序员都不是Android应用开发之路上孤军奋战的一个人,GitHub上浩如烟海的开源框架或类库就是前人为我们发明的轮子,有的轮子能提高软件性能,而有的轮子似乎是以牺牲性能为代价换 ...
随机推荐
- 谈谈 JavaScript 中的 this 指向问题
JavaScript 中的 this 为一个重难点,它不像静态语言 C#.Java 一样,就表示当前对象.而在 JS 中, this 是运行时确定,而并非定义时就已确定其值. 谈起 this ,必须少 ...
- 命令行创建maven模块工程
上一边文章,借助外部eclipse来创建模块项目,本文直接使用maven命令来创建 mvn archetype:generate -DgroupId=com.mycompany.demo -Darti ...
- JS Math 类库介绍
下面介绍下随机生成数的常用几个API JS 随机数生成 : 在JavaScript , 提供了生成随机数的API, Math.random() 1.Math.random() : 随机生成小数 . 生 ...
- C#不安全代码
当一个代码块使用 unsafe 修饰符标记时,C# 允许在函数中使用指针变量.不安全代码或非托管代码是指使用了指针变量的代码块. 下面的实例说明了不安全代码中的指针的定义与调用: static uns ...
- IOS6 字体高亮显示
ios6之前在一个字符串中如果也让某个字体高亮或者特殊显示(如: 关注[ ]),需要用单独一个的标签进行显示,或者利用CoreText进行字体绘绘制,非常麻烦: 现在IOS6 中TextView,la ...
- BZOJ 3170: [Tjoi 2013]松鼠聚会 切比雪夫距离
3170: [Tjoi 2013]松鼠聚会 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- SiteMesh学习笔记
SiteMesh是一个轻量级的web应用框架,实现了Decorator模式.它的目标是将多个页面都将引用的jsp页面通过配置加载到相应的jsp文件中. 在我们的项目中,每个jsp都需要添加两个top和 ...
- CentOS 6.4 安装 thrift-0.9.3
前言 为了能给.NET的程序提供HBase访问接口需要在Hadoop/Spark集群上安装Thrift Thrift介绍 Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强 ...
- Linux编程之《进程/线程绑定CPU》
Intro----- 通常我们在编写服务器代码时,可以通过将当前进程绑定到固定的CPU核心或者线程绑定到固定的CPU核心来提高系统调度程序的效率来提高程序执行的效率,下面将完整代码贴上. /***** ...
- PHP.4-DIV+CSS标准网页布局准备工作(下)
DIV+CSS标准网页布局准备工作 区块属性(区块模型) 属 性 描 述 Margin(注) 是定义区块外边界与上级元素距离的属性,用1到4个值来设置元素的边界,每个值都是长度.百分比或者auto,百 ...