常用的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);
刷新缓存的策略
  1. Media store content - 使用Glide的 MediaStoreSignature 类作为你的签名。MediaStoreSignature 允许你混入修改时间、MIME类型,以及item的方向到缓存键中。
  2. Files - 你可以使用 ObjectKey 来混入文件的修改日期。
  3. 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();

加载和显示任务流如下:

Android识别图形库 android图像类库_github