转载自:http://blog.youkuaiyun.com/ljy_programmer/article/details/78273267
学习/参考地址:
https://www.fresco-cn.org/docs/index.html
http://blog.youkuaiyun.com/wyb112233/article/details/49637685
http://blog.youkuaiyun.com/android_ls/article/details/53137867
前言
Fresco是一个出自Facebook的功能强大的图片加载库
优点:
1)内存自动回收。图片不可见时,会及时自动释放所占用的内存,尽可能地避免OOM
2)三级缓存机制。两级内存缓存(解码的与未解码的)+一级磁盘缓存,提示加载速度,节省内存占用空间
3)支持各种加载场景。如动图加载、高斯模糊、渐进式加载、先加载小图再加载大图,以及其它常见的图片加载场景
缺点:
1)体积较大。较其他主流图片库体积要大一些
2)侵入性较强。须使用它提供的SimpleDraweeView来代替ImageView加载显示图片
综合来说肯定是利大大大于弊,尤其是当你的应用需要加载很多图片时,更能凸显其价值。
介绍
下面通过 配置、SimpleDraweeView、加载图片、混淆、其他 这几个部分来介绍。
1. 配置
1.1 添加依赖
compile 'com.facebook.fresco:fresco:1.5.0'
compile 'com.facebook.fresco:animated-gif:1.5.0'
compile 'com.facebook.fresco:animated-webp:1.5.0'
compile 'com.facebook.fresco:webpsupport:1.5.0'
compile 'com.facebook.fresco:imagepipeline-okhttp3:1.5.0'
1.2 设置磁盘缓存
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
imagePipelineConfigBuilder.setMainDiskCacheConfig(DiskCacheConfig.newBuilder(context)
.setBaseDirectoryPath(context.getExternalCacheDir())
.setBaseDirectoryName(BaseConstants.APP_IMAGE)
.setMaxCacheSize(MAX_DISK_CACHE_SIZE)
.build());
1.3 设置内存缓存
设置已解码的内存缓存(Bitmap缓存)
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
imagePipelineConfigBuilder.setBitmapMemoryCacheParamsSupplier(new Supplier<MemoryCacheParams>() {
public MemoryCacheParams get() {
int MAX_HEAP_SIZE = (int) Runtime.getRuntime().maxMemory();
int MAX_MEMORY_CACHE_SIZE = MAX_HEAP_SIZE / 5;
MemoryCacheParams bitmapCacheParams = new MemoryCacheParams(
MAX_MEMORY_CACHE_SIZE,
Integer.MAX_VALUE,
MAX_MEMORY_CACHE_SIZE,
Integer.MAX_VALUE,
Integer.MAX_VALUE);
return bitmapCacheParams;
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
设置未解码的内存缓存
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
imagePipelineConfigBuilder.setEncodedMemoryCacheParamsSupplier(new Supplier<MemoryCacheParams>() {
public MemoryCacheParams get() {
MemoryCacheParams bitmapCacheParams;
return bitmapCacheParams;
}
});
1.4 设置内存紧张时的应对措施
MemoryTrimmableRegistry memoryTrimmableRegistry = NoOpMemoryTrimmableRegistry.getInstance();
memoryTrimmableRegistry.registerMemoryTrimmable(new MemoryTrimmable() {
@Override
public void trim(MemoryTrimType trimType) {
final double suggestedTrimRatio = trimType.getSuggestedTrimRatio();
if (MemoryTrimType.OnCloseToDalvikHeapLimit.getSuggestedTrimRatio() == suggestedTrimRatio
|| MemoryTrimType.OnSystemLowMemoryWhileAppInBackground.getSuggestedTrimRatio() == suggestedTrimRatio
|| MemoryTrimType.OnSystemLowMemoryWhileAppInForeground.getSuggestedTrimRatio() == suggestedTrimRatio) {
ImagePipelineFactory.getInstance().getImagePipeline().clearMemoryCaches();
}
}
});
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
imagePipelineConfigBuilder.setMemoryTrimmableRegistry(memoryTrimmableRegistry);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
1.5 设置渐进式显示的效果
ProgressiveJpegConfig progressiveJpegConfig = new ProgressiveJpegConfig() {
@Override
public int getNextScanNumberToDecode(int scanNumber) {
return scanNumber + 2;
}
public QualityInfo getQualityInfo(int scanNumber) {
boolean isGoodEnough = (scanNumber >= 5);
return ImmutableQualityInfo.of(scanNumber, isGoodEnough, false);
}
};
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
imagePipelineConfigBuilder.setProgressiveJpegConfig(progressiveJpegConfig);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
设置完效果后,还需在下面介绍的ImageRequest中开启渐进式加载。
1.6 允许解码时调整图片大小
允许后,即可在后面介绍的ImageRequest中对结合ResizeOptions对解码后的图片大小进行调整,从而优化了图片所占大小。默认只支持JPEG图,所以要设置该属性来支持png、jpg、webp。
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
imagePipelineConfigBuilder.setDownsampleEnabled(true);
1.7 开启Log
FLog.setMinimumLoggingLevel(FLog.VERBOSE);
Set<RequestListener> requestListeners = new HashSet<>();
requestListeners.add(new RequestLoggingListener());
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
imagePipelineConfigBuilder.setRequestListeners(requestListeners);
1.8 初始化
上面的各种配置都是通过ImagePipelineConfig进行的,接着需要进行初始化,在Application中初始化即可
ImagePipelineConfig.Builder imagePipelineConfigBuilder = ImagePipelineConfig.newBuilder(context);
ImagePipelineConfig config = imagePipelineConfigBuilder.build();
Fresco.initialize(context, config);
如果想直接使用默认的配置,可以
Fresco.initialize(context);
2. SimpleDraweeView
Fresco要求使用SimpleDraweeView来替换ImageView进行图片的加载与显示,不少人也是因为这一点而不想使用Fresco。
下面介绍SimpleDraweeView在xml中的各种属性
//在最外层布局的属性中加入xmlns:fresco="http://schemas.android.com/apk/res-auto"
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/sdv"
android:layout_width="150dp"
android:layout_height="150dp"
fresco:actualImageScaleType="centerCrop"
fresco:fadeDuration="2000"
fresco:failureImage="@mipmap/ic_launcher"
fresco:failureImageScaleType="centerCrop"
fresco:placeholderImage="@mipmap/ic_launcher"
fresco:placeholderImageScaleType="centerCrop"
fresco:progressBarAutoRotateInterval="1500"
fresco:progressBarImage="@drawable/rotate"
fresco:progressBarImageScaleType="centerCrop"
fresco:retryImage="@mipmap/ic_launcher"
fresco:retryImageScaleType="centerCrop"
fresco:backgroundImage="@mipmap/ic_launcher"
fresco:overlayImage="@mipmap/ic_launcher"
fresco:pressedStateOverlayImage="@mipmap/ic_launcher"
fresco:roundAsCircle="false"
fresco:roundedCornerRadius="7dp"
fresco:roundTopLeft="true"
fresco:roundTopRight="false"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="true"
fresco:roundWithOverlayColor="@color/colorAccent"
fresco:roundingBorderWidth="2dp"
fresco:roundingBorderColor="@color/colorPrimary"
fresco:viewAspectRatio="1"/>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
上面各个属性的作用说明:(来自http://www.jianshu.com/p/8ff81be83101)
| 属性 | 作用说明 |
|---|
| actualImageScaleType | 加载完成的图片的缩放样式 |
| fadeDuration | 由进度条和占位符图片渐变过渡到加载完成的图片所使用的时间间隔 |
| failureImage | 加载失败所使用的图片 |
| failureImageScaleType | 加载失败所使用的图片的缩放样式 |
| placeholderImage | 占位符图片 |
| placeholderImageScaleType | 占位符图片的缩放样式 |
| progressBarAutoRotateInterval | 旋转进度条旋转1圈所需要的时间 |
| progressBarImage | 旋转进度条所使用的图片 |
| progressBarImageScaleType | 旋转进度条所使用的图片的缩放样式 |
| retryImage | 重试所使用的图片 |
| retryImageScaleType | 重试所使用的图片的缩放样式 |
| backgroundImage | 背景图片 |
| overlayImage | 覆盖在加载完成后图片上的叠加图片 |
| pressedStateOverlayImage | 按压状态下的叠加图片 |
| roundAsCircle | 是否将图片剪切为圆形 |
| roundedCornerRadius | 圆角图片时候,圆角的半径大小 |
| roundTopLeft | 左上角是否为圆角 |
| roundTopRight | 右上角是否为圆角 |
| roundBottomLeft | 左下角是否为圆角 |
| roundBottomRight | 右下角是否为圆角 |
| roundWithOverlayColor | 圆角或圆形图叠加的颜色,只能是颜色 |
| roundingBorderWidth | 圆角或圆形图边框的宽度 |
| roundingBorderColor | 圆角或圆形图边框的颜色 |
| viewAspectRatio | 设置宽高比 |
各个属性的效果图,可到http://blog.youkuaiyun.com/wyb112233/article/details/49637685查看,我就不重复造轮子了。
*注意:
1)android:src属性对于SimpleDraweeView无效,必要的话可用fresco:placeholderImage来设置。
2)SimpleDraweeView不支持android:layout_width和android:layout_height同时都设为wrap_content。
3. 加载图片
使用Fresco加载图片,大致是按以下流程进行的。
1. 设置Hierarchay(上面xml中的属性,可在这进行设置)
2. 构建ImageRequest(加载路径、开启渐进式加载、高斯模糊、调整解码图片大小等,可在这进行设置)
3. 构建DraweeController(动图加载、失败后点击重新加载等,可在这进行设置)
4. 进行图片加载
3.1 设置Hierarchay
虽然xml中的属性都能在这一步通过代码进行设置,但一般只在这设置一些统一固定的属性,比如加载占位图、加载失败图等。
Resources res = MyApplication.getInstance().getResources();
Drawable retryImage = ResourcesCompat.getDrawable(res, R.mipmap.ic_image_load, null);
Drawable failureImage = ResourcesCompat.getDrawable(res, R.mipmap.ic_image_load, null);
Drawable placeholderImage = ResourcesCompat.getDrawable(res, R.mipmap.ic_image_load, null);
public void setHierarchay(GenericDraweeHierarchy hierarchy) {
if (hierarchy != null) {
hierarchy.setRetryImage(retryImage);
hierarchy.setFailureImage(failureImage, ScalingUtils.ScaleType.CENTER_CROP);
hierarchy.setPlaceholderImage(placeholderImage, ScalingUtils.ScaleType.CENTER_CROP);
hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
3.2 构建ImageRequest
/**
* 构建、获取ImageRequest
* @param uri 加载路径
* @param progressiveRenderingEnabled 是否开启渐进式加载
* @param blurEnable 是否开启高斯模糊
* @param simpleDraweeView 加载的图片控件
* @return ImageRequest
*/
public ImageRequest getImageRequest(Uri uri, boolean progressiveRenderingEnabled, boolean blurEnable, SimpleDraweeView simpleDraweeView) {
int width;
int height;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
width = simpleDraweeView.getWidth();
height = simpleDraweeView.getHeight();
} else {
width = simpleDraweeView.getMaxWidth();
height = simpleDraweeView.getMaxHeight();
}
ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(uri);
if (width > 0 && height > 0) {
builder.setResizeOptions(new ResizeOptions(width, height));
}
builder.setProgressiveRenderingEnabled(progressiveRenderingEnabled);
if (blurEnable) {
builder.setPostprocessor(new BasePostprocessor() {
@Override
public String getName() {
return "blurPostprocessor";
}
@Override
public void process(Bitmap bitmap) {
BitmapBlurHelper.blur(bitmap, 15);
}
});
}
return builder.build();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
3.3 构建DraweeController
/**
* 构建、获取Controller
* @param request
* @param oldController
* @return
*/
public DraweeController getController(ImageRequest request, @Nullable DraweeController oldController) {
PipelineDraweeControllerBuilder builder = Fresco.newDraweeControllerBuilder();
builder.setImageRequest(request);
builder.setTapToRetryEnabled(false);
builder.setAutoPlayAnimations(true);
builder.setOldController(oldController);
return builder.build();
}
3.4 进行图片加载
创建一个loadImage方法将上面的Hierarchy、ImageRequest、DraweeController串在一起,供具体的加载场景使用
/**
* 加载图片核心方法
*
* @param simpleDraweeView 图片加载控件
* @param uri 图片加载地址
* @param progressiveRenderingEnabled 是否开启渐进式加载
* @param blurEnable 是否开启高斯模糊效果
*/
public void loadImage(SimpleDraweeView simpleDraweeView, Uri uri, boolean progressiveRenderingEnabled, boolean blurEnable) {
setHierarchay(simpleDraweeView.getHierarchy());
ImageRequest imageRequest = getImageRequest(uri, progressiveRenderingEnabled, blurEnable, simpleDraweeView);
DraweeController draweeController = getController(imageRequest, simpleDraweeView.getController());
simpleDraweeView.setController(draweeController);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
具体的加载场景:
- 加载网络图片,包括gif/webp动图
public void loadNetImage(SimpleDraweeView simpleDraweeView, String url) {
Uri uri = Uri.parse(url);
loadImage(simpleDraweeView, uri, false, false);
}
public void loadLocalImage(SimpleDraweeView simpleDraweeView, String fileName) {
Uri uri = Uri.parse("file://" + fileName);
loadImage(simpleDraweeView, uri, false, false);
}
public void loadResourceImage(SimpleDraweeView simpleDraweeView, @DrawableRes int resId) {
Uri uri = Uri.parse("res:///" + resId);
loadImage(simpleDraweeView, uri, false, false);
}
public void loadContentProviderImage(SimpleDraweeView simpleDraweeView, int resId) {
Uri uri = Uri.parse("content:///" + resId);
loadImage(simpleDraweeView, uri, false, false);
}
public void loadAssetImage(SimpleDraweeView simpleDraweeView, int resId) {
Uri uri = Uri.parse("asset:///" + resId);
loadImage(simpleDraweeView, uri, false, false);
}
- 加载网络图片,先加载小图,待大图加载完成后再替换掉小图
这个需要修改一下DraweeController的构建,通过setLowResImageRequest来添加小图请求
public DraweeController getSmallToBigController(ImageRequest smallRequest, ImageRequest bigRequest, @Nullable DraweeController oldController) {
PipelineDraweeControllerBuilder builder = Fresco.newDraweeControllerBuilder();
builder.setLowResImageRequest(smallRequest);
builder.setImageRequest(bigRequest);
builder.setTapToRetryEnabled(false);
builder.setAutoPlayAnimations(true);
builder.setOldController(oldController);
return builder.build();
}
public void loadImageSmallToBig(SimpleDraweeView simpleDraweeView, Uri smallUri, Uri bigUri) {
setHierarchay(simpleDraweeView.getHierarchy());
ImageRequest smallRequest = getImageRequest(smallUri, false, false, simpleDraweeView);
ImageRequest bigRequest = getImageRequest(bigUri, false, false, simpleDraweeView);
DraweeController draweeController = getSmallToBigController(smallRequest, bigRequest, simpleDraweeView.getController());
simpleDraweeView.setController(draweeController);
}
public void loadNetImageSmallToBig(SimpleDraweeView simpleDraweeView, String smallUrl, String bigUrl) {
Uri smallUri = Uri.parse(smallUrl);
Uri bigUri = Uri.parse(bigUrl);
loadImageSmallToBig(simpleDraweeView, smallUri, bigUri);
}
4. 混淆
在proguard-rules.pro文件中添加以下内容进行混淆配置
#fresco开始
-keep class com.facebook.fresco.** { *
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.common.internal.DoNotStrip *
}
-keep class com.facebook.imagepipeline.gif.** { *
-keep class com.facebook.imagepipeline.webp.* { *
-keepclassmembers class * {
native <methods>
}
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**
-keep class com.facebook.imagepipeline.animated.factory.AnimatedFactoryImpl {
public AnimatedFactoryImpl(com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory,com.facebook.imagepipeline.core.ExecutorSupplier)
}
#fresco结束
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
5. 其他
5.1 缓存策略
Fresco采用三级缓存机制,两级内存缓存+一级磁盘缓存,其中两级内存缓存分为已解码的图片缓存(Bitmap缓存)和未解码的图片缓存。
下面通过加载流程来了解其缓存策略。
1. 根据Uri到已解码的图片缓存中查找是否存在对应的Bitmap。如果存在,则返回Bitmap显示;
如果不存在,则到未解码的图片缓存中查找。
2. 如果在未解码的图片缓存中存在对应的数据,则解码,返回Bitmap显示并将其加入到已解码的图片缓存中;如果不存在,则到磁盘缓存中查找。
3. 如果在磁盘缓存中存在对应的数据,则将数据加入到未解码的图片缓存中,然后解码,返回Bitmap显示并将其加入到已解码的图片缓存中;如果不存在,则进行网络请求或者到本地文件加载。
4. 请求或加载成功后,将数据加入到磁盘缓存和未解码的图片缓存中,然后解码,返回Bitmap显示并将其加入到已解码的图片缓存中。
简单整了个示意图,帮助理解下:

5.2 兼容共享动画
android5.0之后加入了共享动画,
相关的学习地址:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0201/2394.html
http://jcodecraeer.com/a/opensource/2015/0113/2311.html?1422794518
如果直接结合Fresco和共享动画来实现页面的过渡效果,会发现无效或异常。
Fresco官方也给出了说明,https://www.fresco-cn.org/docs/shared-transitions.html
兼容方法:
1.重写共享动画转换效果的xml文件,注释掉changeImageTransform,并将该文件放于res/transition文件夹下
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<explode/>
<changeBounds/>
<changeTransform/>
<changeClipBounds/>
</transitionSet>
2.在style文件中使用上一步重写的xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<!-- 允许使用transitions -->
<item name="android:windowContentTransitions">true</item>
<!-- 指定shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/share_element_transition</item>
<item name="android:windowSharedElementExitTransition">
@transition/share_element_transition</item>
</style>
</resources>
5.3 浏览大图
“点击小图浏览大图,并且大图支持缩放。”
这种需求经常能见到,上面提到的SimpleDraweeView并不支持缩放等功能,所以需要重新定制一个控件来显示。
官方给出了一个ZoomableDraweeView来支持该场景,另外也可以参考PhotoDraweeView
5.4 获取网络请求回来的Bitmap
有时候,我们需要拿到网络请求回来的Bitmap对象,那么我们可以这么做:
public final void loadImageBitmap(String url, FrescoBitmapCallback<Bitmap> callback) {
if (TextUtils.isEmpty(url)) {
return;
}
try {
fetch(Uri.parse(url), callback);
} catch (Exception e) {
e.printStackTrace();
callback.onFailure(Uri.parse(url), e);
}
}
private void fetch(final Uri uri, final FrescoBitmapCallback<Bitmap> callback) throws Exception {
ImageRequestBuilder requestBuilder = ImageRequestBuilder.newBuilderWithSource(uri);
ImageRequest imageRequest = requestBuilder.build();
DataSource<CloseableReference<CloseableImage>> dataSource =
ImagePipelineFactory.getInstance().getImagePipeline().fetchDecodedImage(imageRequest, null);
dataSource.subscribe(new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(@Nullable final Bitmap bitmap) {
if (callback == null) return;
if (bitmap != null && !bitmap.isRecycled()) {
Executors.newSingleThreadExecutor().submit(new Callable<Bitmap>() {
@Override
public Bitmap call() throws Exception {
final Bitmap resultBitmap = bitmap.copy(bitmap.getConfig(), bitmap.isMutable());
if (resultBitmap != null && !resultBitmap.isRecycled()) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.onSuccess(uri, resultBitmap);
}
});
}
return resultBitmap;
}
});
}
}
@Override
public void onCancellation(DataSource<CloseableReference<CloseableImage>> dataSource) {
super.onCancellation(dataSource);
if (callback == null) return;
callback.onCancel(uri);
}
@Override
public void onFailureImpl(DataSource dataSource) {
if (callback == null) return;
Throwable throwable = null;
if (dataSource != null) {
throwable = dataSource.getFailureCause();
}
callback.onFailure(uri, throwable);
}
}, UiThreadImmediateExecutorService.getInstance());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
public interface FrescoBitmapCallback<T> {
void onSuccess(Uri uri, T result);
void onFailure(Uri uri, Throwable throwable);
void onCancel(Uri uri);
}
使用
demo中已将前面介绍的配置、加载图片的方法等都封装到FrescoUtil类中。大家可以根据自己的需求到FrescoUitl中进行修改定制。
1.在Application中初始化
FrescoUtil.getInstance().initializeFresco(this);
2.在需要加载图片的地方调用相关方法
FrescoUtil.getInstance().loadNetImage(simpleDraweeView, imageUrl);
FrescoUtil.getInstance().loadResourceImage(simpleDraweeView, resId);
....
详细代码请看demo,地址:https://github.com/LJYcoder/DevBase
demo的内容流程,请看《安卓开发框架(MVP+主流框架+基类+工具类)— 开篇》