常用的Android图片加载库有:Glide、Picasso、Fresco、Universal-Image-Loader。其github地址如下:
- Universal-Image-Loader:https://github.com/nostra13/Android-Universal-Image-Loader
- Fresco:https://github.com/facebook/fresco
- Picasso:https://github.com/square/picasso
- Glide:https://github.com/bumptech/glide
1. Glide(我认为最好用的一个)
1.1 基本用法
- 引入库文件:
// Gradle
dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}
// Maven
<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide</artifactId>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>compiler</artifactId>
<version>4.11.0</version>
<optional>true</optional>
</dependency>
- AndroidManifest.xml中添加网络权限、读写权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package.name"
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
...
</application>
</manifest>
- 配置proguard.cfg
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# 若Android API 高于27添加以下(不需要/):
/```pro
-dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
- 简单示例代码:
// For a simple view:
@Override public void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
}
// For a simple image list:
@Override public View getView(int position, View recycled, ViewGroup container) {
final ImageView myImageView;
if (recycled == null) {
myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container, false);
} else {
myImageView = (ImageView) recycled;
}
String url = myUrls.get(position);
RequestOptions cropOptions = new RequestOptions().centerCrop(context);
......
Glide
.with(myFragment)
.load(url)
// .thumbnail(Glide.with(fragment).load(thumbnailUrl)) # 加载缩略图,对本地和远程图片都适用;指定加载的低分辨率缩略图
// .override(thumbnailSize)) # 若你只想加载一个本地图像,或者你只有一个单独的远程图片
// .thumbnail(/*sizeMultiplier=*/ 0.25f) # 以上代码也可以这样实现
.centerCrop()
.error(Glide.with(fragment).load(fallbackUrl)) # 主请求失败时加载该请求
// .apply(cropOptions) # 应用的不同部分之间共享相同的加载选项
.fallback( R.drawable.empty) # 当传递null时,此时显示的图片
// .placeholder(R.drawable.loading_spinner) # 默认占位图
.into(myImageView);
return myImageView;
}
1.2 Glide图片缓存
Glide会在开始一个新的图片请求之前会先检查内存(Active Resources、Memory cache),后检查磁盘(Resource、Data),若都没有则从URL获取。
磁盘缓存策略(Disk Cache Strategy)
默认的策略叫做AUTOMATIC,它会尝试对本地和远程图片使用最佳的策略。当你加载远程数据时,AUTOMATIC 策略仅会存储未被你的加载过程修改过的原始数据。对于本地数据,AUTOMATIC 策略则会仅存储变换过的缩略图。
指定DiskCacheStrategy为:
Glide.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
DiskCacheStrategy还有以下几种方式:
- DiskCacheStrategy.ALL :所有版本都会缓存
- DiskCacheStrategy.NONE :不做缓存
- DiskCacheStrategy.SOURCE :只缓存原图
- DiskCacheStrategy.RESULT :缓存最后一次图片
仅从缓存加载图片:
Glide.with(fragment)
.load(url)
.onlyRetrieveFromCache(true)
.into(imageView);
跳过缓存:
//仅跳过内存缓存
Glide.with(fragment)
.load(url)
.skipMemoryCache(true)
.into(view);
//仅跳过磁盘缓存
Glide.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(view);
//两者都跳过
Glide.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(view);
刷新缓存的策略
- Media store content - 使用Glide的 MediaStoreSignature 类作为你的签名。MediaStoreSignature 允许你混入修改时间、MIME类型,以及item的方向到缓存键中。
- Files - 你可以使用 ObjectKey 来混入文件的修改日期。
- Urls - 你可以在内容变更时对URL做出改变。
Glide.with(yourFragment)
.load(yourFileDataModel)
// .signature(new ObjectKey(yourVersionMetadata))
// .signature(new MediaStoreSignature(mimeType, dateModified, orientation))
.into(yourImageView);
你还可以定义你自己的签名。
如何集成OkHttp3、Volley、RecyclerView?请见:http://bumptech.github.io/glide/int/about.html
2. picasso
1.1 基本用法
- 引入库文件:
// Gradle
dependencies {
implementation 'com.squareup.picasso:picasso:2.71828'
}
// Maven
<dependency>
<groupId>com.squareup.picasso</groupId>
<artifactId>picasso</artifactId>
<version>2.71828</version>
</dependency>
简单示例代码:
Picasso.get()
.load(url)
.resize(50, 50) //更改大小
.centerCrop()
.fetch() //预加载
.priority(Picasso.Priority.HIGH) //加载优先级
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(imageView, new Callback() { //加载并回调
@Override
public void onSuccess() {
}
@Override
public void onError(Exception e) {
}
});
3. fresco
1.1 基本用法
- 引入库文件:
// Gradle
dependencies {
// 在 API < 14 上的机器支持 WebP 时,需要添加
compile 'com.facebook.fresco:animated-base-support:0.12.0'
// 支持 GIF 动图,需要添加
compile 'com.facebook.fresco:animated-gif:0.12.0'
// 支持 WebP (静态图+动图),需要添加
compile 'com.facebook.fresco:animated-webp:0.12.0'
compile 'com.facebook.fresco:webpsupport:0.12.0'
// 仅支持 WebP 静态图,需要添加
compile 'com.facebook.fresco:webpsupport:0.12.0'
// 其他依赖
compile 'com.facebook.fresco:fresco:0.12.0'
}
简单示例代码:
//在MainActivity中
@Override
public void onCreate() {
super.onCreate();
//需要在此初始化
Fresco.initialize(this);
}
//在xml布局文件中
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="130dp"
android:layout_height="130dp"
fresco:placeholderImage="@drawable/my_drawable"
/>
//开始加载图片
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);
多图请求:
Uri lowResUri, highResUri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setLowResImageRequest(ImageRequest.fromUri(lowResUri))
.setImageRequest(ImageRequest.fromUri(highResUri))
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
缩略图预览:
Uri uri;
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setLocalThumbnailPreviewsEnabled(true)
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
加载最先可用的图片:
Uri uri1, uri2;
ImageRequest request = ImageRequest.fromUri(uri1);
ImageRequest request2 = ImageRequest.fromUri(uri2);
ImageRequest[] requests = { request1, request2 };
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setFirstAvailableImageRequests(requests)
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
4. Android-Universal-Image-Loader
1.1 基本用法
- 引入库文件:
// Gradle
dependencies {
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}
// Maven
<dependency>
<groupId>com.nostra13.universalimageloader</groupId>
<artifactId>universal-image-loader</artifactId>
<version>1.9.5</version>
</dependency>
简单示例代码:
public class MyActivity extends Activity {
@Override
public void onCreate() {
super.onCreate();
// Create global configuration and initialize ImageLoader with this config
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
...
.build();
ImageLoader.getInstance().init(config);
...
}
}
ImageLoader imageLoader = ImageLoader.getInstance();
// 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);
参数选项有:
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub) // resource or drawable
.showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable
.showImageOnFail(R.drawable.ic_error) // resource or drawable
.resetViewBeforeLoading(false) // default
.delayBeforeLoading(1000)
.cacheInMemory(false) // default
.cacheOnDisk(false) // default
.preProcessor(...)
.postProcessor(...)
.extraForDownloader(...)
.considerExifParams(false) // default
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
.bitmapConfig(Bitmap.Config.ARGB_8888) // default
.decodingOptions(...)
.displayer(new SimpleBitmapDisplayer()) // default
.handler(new Handler()) // default
.build();
加载和显示任务流如下: