在 APP 开发中,网络图片的处理和加载是非常重要的一部分,图片处理如果做的不好会导致 OOM 及 APP 体验卡顿不流畅。所以本课程将会通过两个目前比较强大的图片处理库帮助大家学习图片处理这部分。
1.Android 主流网络图片加载缓存库框架 Android-Universal-ImageLoader 和 Picasso 的各自特点和优势
2.Android-Universal-ImageLoader 的用法和案例
3.Picasso 的用法和案例
Android中图片处理存在的难点:
• OOM内存溢出
• 图片尺寸和缩略图处理的平衡
• 网络图片的加载与缓存机制
这里将会选择两款比较优秀的开源图片处理库框架:Universal-ImageLoader和Picasso为大家进行讲解。
Universal-ImageLoader的简介和特点:
Universal-ImageLoader是目前Android主流的图片处理库框架之一,作者是白俄罗斯的Sergey Tarasevich。
在Android图片处理中需要考虑的问题很多,例如OOM、图片缓存和网络图片加载、多线程问题及图片压缩处理等等复杂的问题。但是Universal-ImageLoader已经帮我们把这些问题处理好了,对外提供了相应的完善的请求API,我们只需要按照要求使用即可。
Universal-ImageLoader特点:
• 支持本地图片和网络图片的多线程异步加载和缓存处理
• 个性化的配置自己项目的ImageLoader
• 图片加载过程的监听回调
• 自动对加载的图片针对当前剩余内存进行裁剪优化,防止OOM
• 较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片
缺点:没有对本地文件压缩处理的相关API方法以及默认都是Src模式设置图片,没有针对Background属性开放API。
Picasso的简介和特点
Picasso是Square公司开源的一个Android图形缓存库。可以实现图片下载和缓存功能。
特点:
• 加载载网络或本地图片并自动缓存处理
• 链式调用
• 图形转换操作,如变换大小,旋转等,提供了接口来让用户可以自定义转换操作
• 在Adapter中回收和取消当前的下载功能
总结:
• 都有高效的网络图片下载和缓存性能
• Universal-ImageLoader功能多,灵活使用配置
• Picasso使用复杂的图片压缩转换来尽可能的减少内存消耗
• 在Adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题。
本课时主要介绍Universal-ImageLoader的用法,包含以下几个知识点:
• Universal-ImageLoader的配置
• 用Universal-ImageLoader加载网络图片和本地图片
Universal-ImageLoader的配置
可以全局配置:在Application里进行配置。
可以针对单一加载图片的地方配置。
例如:可配置图片缓存保存路径、线程池内加载的数量、缓存的文件数量 、每个缓存文件的最大长宽、加载过程中和加载失败时显示的图片等等。
用Universal-ImageLoader加载网络图片和本地图片
Universal-ImageLoader支持网络图片的加载和本地图片的加载,而且可以自动缓存、自动根据当前手机环境进行压缩处理防止出现OOM。
也可以监听整个图片的加载过程,可控。
接下来通过一个实例讲解这两个知识点(Universal-ImageLoader的配置和用Universal-ImageLoader加载网络图片和本地图片)
先将universal-image-loader-1.9.3.jar这个jar包拷贝到项目中,Universal-ImageLoader的配置一般都使用全局的配置所以将配置放到Application中(以下是一个自定义的Application将配置信息写到里面)
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)
// max width, max height,即保存的每个缓存文件的最大长宽
.discCacheExtraOptions(480, 800, null)
// 保存到硬盘的每个缓存文件的最大长宽
// Can slow ImageLoader, use it carefully (Better don't use
// it)/设置缓存的详细信息,最好不要设置这个
.threadPoolSize(3)
// 线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
// You can pass your own memory cache
// implementation/你可以通过自己的内存缓存实现
.memoryCacheSize(2 * 1024 * 1024)
.discCacheSize(50 * 1024 * 1024)
.discCacheFileNameGenerator(new Md5FileNameGenerator())
// 将保存的时候的URI名称用MD5 加密
.tasksProcessingOrder(QueueProcessingType.LIFO)
.discCacheFileCount(100)
// 缓存的文件数量
.discCache(
new UnlimitedDiscCache(new File(Environment
.getExternalStorageDirectory()
+ "/myApp/imgCache")))
// 自定义缓存路径
.defaultDisplayImageOptions(getDisplayOptions())
// 加载图片的一个默认配置信息
.imageDownloader(
new BaseImageDownloader(this, 5 * 1000, 30 * 1000))
//图片加载过程中的配置30 * 1000加载超时的时间 5 * 1000连接时间
.writeDebugLogs() // Remove for release app
// 写入加载的错误日志
.build();// 开始构建
ImageLoader.getInstance().init(config);
}
private DisplayImageOptions getDisplayOptions() {
DisplayImageOptions options;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher) // 设置图片在下载期间显示的图片
.showImageForEmptyUri(R.drawable.ic_launcher)// 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.ic_launcher) // 设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true)// 设置下载的图片是否缓存在内存中
.cacheOnDisc(true)// 设置下载的图片是否缓存在SD卡中
.considerExifParams(true) // 是否考虑JPEG图像EXIF参数(旋转,翻转)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)// 设置图片以如何的编码方式显示
.bitmapConfig(Bitmap.Config.RGB_565)// 设置图片的解码类型//
// .delayBeforeLoading(int delayInMillis)//int
// delayInMillis为你设置的下载前的延迟时间
// 设置图片加入缓存前,对bitmap进行设置
// .preProcessor(BitmapProcessor preProcessor)
.resetViewBeforeLoading(true)// 设置图片在下载前是否重置,复位
.displayer(new RoundedBitmapDisplayer(20))// 是否设置为圆角,弧度为多少
.displayer(new FadeInBitmapDisplayer(100))// 是否图片加载好后渐入的动画时间
.build();// 构建完成
return options;
}
}
在ImageLoaderConfiguration 的配置中可以不要把所有的配置信息都写完,根据需要把几个重要的配置上就行,接下来用Universal-ImageLoader加载网络图片和本地图片。
public class MainActivity extends Activity {
private ImageLoader loader;
private ImageView iv_img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loader = ImageLoader.getInstance();
iv_img = (ImageView) this.findViewById(R.id.iv_img);
String uri = "file:///" + "本地路径";
// loader.displayImage(
// "http://s1.jikexueyuan.com/current/static/images/logo.png",
// iv_img);
loader.displayImage(
"http://s1.jikexueyuan.com/current/static/images/logo.png",
iv_img, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String arg0, View arg1) {
Log.i("info", "onLoadingStarted");
}
@Override
public void onLoadingFailed(String arg0, View arg1,
FailReason arg2) {
Log.i("info", "onLoadingFailed");
}
@Override
public void onLoadingComplete(String arg0, View arg1,
Bitmap arg2) {
Log.i("info", "onLoadingComplete");
}
@Override
public void onLoadingCancelled(String arg0, View arg1) {
Log.i("info", "onLoadingCancelled");
}
});
}
}
注:测试记得加入网络访问权限和SDCard的读写权限
本课时主要介绍Async-http的用法,包含以下几个知识点:
• Picasso的几个重要方法的介绍
• 用Picasso加载网络图片和本地图片
Picasso的几个重要方法的介绍
图片异步加载:
Picasso.with(context).load(“http://baidu.com/logo.png“).into(imageView);
图片转换:转换图片以适应布局大小并减少内存占用
Picasso.with(context).load(url).resize(50,50) .centerCrop() .into(imageView);
Adapter 中的下载:Adapter的重用会被自动检测到,Picasso会取消上次的加载
空白或者错误占位图片设置方法及本地资源文件的加载方法
用Picasso加载网络图片和本地图片
Picasso采用链式调用加载和处理图片方式。
除了加载网络图片,picasso还支持加载Resources, assets, files, contentproviders中的本地资源文件。
接下来通过实例讲解这两个知识点(Picasso的几个重要方法的介绍和用Picasso加载网络图片和本地图片)
将picasso-2.4.0.jar拷贝到项目中,到AndroidManifest.xml中配置相关的权限
public class MainActivity extends Activity {
private ImageView iv_img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_img = (ImageView) this.findViewById(R.id.iv_img);
Picasso.with(this)
.load("http://s1.jikexueyuan.com/current/static/images/logo.png")
.into(iv_img);
Picasso.with(this)
.load("http://s1.jikexueyuan.com/current/static/images/logo.png")
.resize(50, 50).into(iv_img);
Picasso.with(this)
.load("http://s1.jikexueyuan.com/current/static/images/logo.png")
.error(R.drawable.ic_launcher).into(iv_img);
}
}
本套课程中我们学习了2款Android网络图片加载缓存处理库的使用,你应当掌握了以下知识:
• 两款图片处理库的特点和不同
• Universal-ImageLoader基础用法
• Picasso的基础用法
你可以使用这些技术来制作一个基于图片相关的App,如果想继续提高,你可以继续研究相关的拓展方法。