版权声明:本文为延成原创文章,转载请标明出处
经过在实际项目中多次的使用,本人在这做了一下简单总结,希望对初次使用和正在使用的你们有所帮助。
官方github地址:https://github.com/facebook/fresco
官方地址:https://www.fresco-cn.org/
优点:
缺点:
1.gradle引用
dependencies {
//基础功能引用
compile 'com.facebook.fresco:fresco:0.14.1'
//支持GIF动图,需要添加
compile 'com.facebook.fresco:animated-gif:0.14.1'
//支持WebP动图,需要添加
compile 'com.facebook.fresco:animated-webp:0.14.1'
//支持WebP静态图,需要添加
compile 'com.facebook.fresco:webpsupport:0.14.1'
//支持okhttp3,需要添加
compile 'com.facebook.fresco:imagepipeline-okhttp3:0.14.1'
}
2.初始化并配置fresco
在Application中做初始化
Fresco.initialize(this, ImageLoaderConfig.getImagePipelineConfig(this));
自定义配置ImageLoaderConfig类
/**
* Created by corleone.
*/
public class ImageLoaderConfig {
private static final String IMAGE_PIPELINE_CACHE_DIR = "image_cache";
private static final String IMAGE_PIPELINE_SMALL_CACHE_DIR = "image_small_cache";
private static final int MAX_DISK_SMALL_CACHE_SIZE = 10 * ByteConstants.MB;
private static final int MAX_DISK_SMALL_ONLOWDISKSPACE_CACHE_SIZE = 5 * ByteConstants.MB;
private static ImagePipelineConfig sImagePipelineConfig;
/**
* Creates config using android http stack as network backend.
*/
public static ImagePipelineConfig getImagePipelineConfig(final Context context) {
if (sImagePipelineConfig == null) {
/**
* 推荐缓存到应用本身的缓存文件夹,这么做的好处是:
* 1、当应用被用户卸载后能自动清除缓存,增加用户好感
* 2、一些内存清理软件可以扫描出来,进行内存的清理
*/
File fileCacheDir = context.getApplicationContext().getCacheDir();
// if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
// fileCacheDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Fresco");
// }
DiskCacheConfig mainDiskCacheConfig = DiskCacheConfig.newBuilder(context)
.setBaseDirectoryName(IMAGE_PIPELINE_CACHE_DIR)
.setBaseDirectoryPath(fileCacheDir)
.build();
DiskCacheConfig smallDiskCacheConfig = DiskCacheConfig.newBuilder(context)
.setBaseDirectoryPath(fileCacheDir)
.setBaseDirectoryName(IMAGE_PIPELINE_SMALL_CACHE_DIR)
.setMaxCacheSize(MAX_DISK_SMALL_CACHE_SIZE)
.setMaxCacheSizeOnLowDiskSpace(MAX_DISK_SMALL_ONLOWDISKSPACE_CACHE_SIZE)
.build();
FLog.setMinimumLoggingLevel(FLog.VERBOSE);
Set<RequestListener> requestListeners = new HashSet<>();
requestListeners.add(new RequestLoggingListener());
// 当内存紧张时采取的措施
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
) {
// 清除内存缓存
Fresco.getImagePipeline().clearMemoryCaches();
}
}
});
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.retryOnConnectionFailure(false)
.build();
sImagePipelineConfig = OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient)
// .setBitmapsConfig(Bitmap.Config.RGB_565) // 若不是要求忒高清显示应用,就用使用RGB_565吧(默认是ARGB_8888)
.setDownsampleEnabled(true) // 在解码时改变图片的大小,支持PNG、JPG以及WEBP格式的图片,与ResizeOptions配合使用
// 设置Jpeg格式的图片支持渐进式显示
.setProgressiveJpegConfig(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);
}
})
.setRequestListeners(requestListeners)
.setMemoryTrimmableRegistry(memoryTrimmableRegistry) // 报内存警告时的监听
// 设置内存配置
// .setBitmapMemoryCacheParamsSupplier(new BitmapMemoryCacheParamsSupplier(
// (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)))
.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;
}
})
.setEncodedMemoryCacheParamsSupplier(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;
}
})
.setMainDiskCacheConfig(mainDiskCacheConfig) // 设置主磁盘配置
.setSmallImageDiskCacheConfig(smallDiskCacheConfig) // 设置小图的磁盘配置
.build();
}
return sImagePipelineConfig;
}
}
3.在xml中基本使用
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/sdv_head"
android:layout_width="60dp"
android:layout_height="60dp"
fresco:placeholderImage="@mipmap/ic_launcher"
/>
//在布局根节点添加
xmlns:fresco="http://schemas.android.com/apk/res-auto"
4.代码中基本加载
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/fresco-logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);
1.在XML中高级使用SimpleDraweeView:
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="20dp"
android:layout_height="20dp"
fresco:fadeDuration="300"//渐进时间
fresco:actualImageScaleType="focusCrop"
fresco:placeholderImage="@color/wait_color"
fresco:placeholderImageScaleType="fitCenter"
fresco:failureImage="@drawable/error"//失败时显示的图片
fresco:failureImageScaleType="centerInside"//失败图片的显示方式
fresco:retryImage="@drawable/retrying"//重试图
fresco:retryImageScaleType="centerCrop"//重试图显示方式
fresco:progressBarImage="@drawable/progress_bar"
fresco:progressBarImageScaleType="centerInside"
fresco:progressBarAutoRotateInterval="1000"
fresco:backgroundImage="@color/blue"
fresco:overlayImage="@drawable/watermark"
fresco:pressedStateOverlayImage="@color/red"
fresco:roundAsCircle="false"
fresco:roundedCornerRadius="1dp"
fresco:roundTopLeft="true"
fresco:roundTopRight="false"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="true"
fresco:roundWithOverlayColor="@color/corner_color"
fresco:roundingBorderWidth="2dp"
fresco:roundingBorderColor="@color/border_color"
/>
2.在代码中的高级使用,为了方便本人已经封装成Fresco工具类
/**
* Created by corleone.
*/
public class FrescoUtils {
/**
* 显示http或者https远程图片。
*
* @param draweeView imageView。
* @param url 连接地址。
*/
public static void showUrl(SimpleDraweeView draweeView, String url) {
if (TextUtils.isEmpty(url))
draweeView.setImageURI(Uri.parse("res:///" + R.drawable.bg_rect_placeholder_main_gray));
try {
draweeView.setImageURI(Uri.parse(url));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示远程图并加入自定义旋转动画
*
* @param draweeView
* @param url
*/
public static void showUrlAnima(SimpleDraweeView draweeView, String url) {
if (TextUtils.isEmpty(url))
draweeView.setImageURI(Uri.parse("res:///" + R.drawable.bg_rect_placeholder_main_gray));
try {
draweeView.setImageURI(Uri.parse(url));
Animation animation = AnimationUtils.loadAnimation(HiMicApplication.getInstance(), R.anim.rotate_anim);
draweeView.setAnimation(animation);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示bitmap图
*
* @param context
* @param draweeView
* @param mBitmap
*/
public static void showBitmap(Context context, SimpleDraweeView draweeView, Bitmap mBitmap) {
Uri uri = null;
if (mBitmap == null) {
draweeView.setImageURI(Uri.parse("res:///" + R.drawable.bg_rect_placeholder_main_gray));
} else {
uri = Uri.parse(MediaStore.Images.Media.insertImage(context.getContentResolver(), mBitmap, null, null));
}
try {
draweeView.setImageURI(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示远程图,并对图做圆角处理
* 为了防止builder被多次new,所以用到时传进来
*GenericDraweeHierarchyBuilder mBuilder = new GenericDraweeHierarchyBuilder(context.getResources());
* @param draweeView
* @param url
* @param builder
* @param corners
*/
public static void showCornerUrl(SimpleDraweeView draweeView, String url, GenericDraweeHierarchyBuilder builder,int corners) {
RoundingParams roundingParams = new RoundingParams();
roundingParams.setCornersRadii(corners, corners, corners, corners);
GenericDraweeHierarchy hierarchy = builder
.setActualImageScaleType(ScalingUtils.ScaleType.FOCUS_CROP)
.setFailureImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE)
.build();
hierarchy.setRoundingParams(roundingParams);
draweeView.setHierarchy(hierarchy);
if (url == null)
draweeView.setImageURI(Uri.parse("res:///" + R.drawable.bg_rect_placeholder_main_gray));
try {
draweeView.setImageURI(Uri.parse(url));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 清除指定图片url缓存
*
* @param draweeView
* @param url
*/
public static void clearCacheShowUrl(SimpleDraweeView draweeView, String url) {
if (TextUtils.isEmpty(url))
return;
Uri uri = Uri.parse(url);
ImagePipeline imagePipeline = Fresco.getImagePipeline();
imagePipeline.evictFromMemoryCache(uri);
imagePipeline.evictFromDiskCache(ImageRequest.fromUri(uri));
// combines above two lines
imagePipeline.evictFromCache(uri);
try {
draweeView.setImageURI(Uri.parse(url));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示一个本地图片。
*
* @param draweeView imageView。
* @param path 路径。
* @param width 实际宽。
* @param height 实际高度。
*/
public static void showFile(SimpleDraweeView draweeView, String path, int width, int height) {
try {
Uri uri = Uri.parse("file://" + path);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setResizeOptions(new ResizeOptions(width, height))
.build();
AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
.setOldController(draweeView.getController())
.setImageRequest(request)
.build();
draweeView.setController(controller);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示本地图片。
*
* @param draweeView imageView。
* @param path 路径。
*/
public static void showFile(SimpleDraweeView draweeView, String path) {
try {
Uri uri = Uri.parse("file://" + path);
draweeView.setImageURI(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示一个Res中的图片。
*
* @param draweeView ImageView。
* @param resId 资源ID。
*/
public static void showRes(SimpleDraweeView draweeView, @DrawableRes int resId) {
try {
draweeView.setImageURI(Uri.parse("res:///" + resId));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示content provider图片。
*
* @param draweeView image view。
* @param path 路径。
*/
public static void showContentProvider(SimpleDraweeView draweeView, String path) {
try {
draweeView.setImageURI(Uri.parse("content://" + path));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 显示Assets中的图片。
*
* @param draweeView ImageView.
* @param path 路径。
*/
public static void showAsset(SimpleDraweeView draweeView, String path) {
try {
draweeView.setImageURI(Uri.parse("asset://" + path));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 以高斯模糊显示。
*
* @param draweeView View。
* @param url url.
* @param iterations 迭代次数,越大越魔化。
* @param blurRadius 模糊图半径,必须大于0,越大越模糊。
*/
public static void showUrlBlur(SimpleDraweeView draweeView, String url, int iterations, int blurRadius) {
try {
Uri uri = Uri.parse(url);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setPostprocessor(new IterativeBoxBlurPostProcessor(iterations, blurRadius))
.build();
AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
.setOldController(draweeView.getController())
.setImageRequest(request)
.build();
draweeView.setController(controller);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 加载图片成bitmap。
*
* @param imageUrl 图片地址。
*/
public static void loadToBitmap(String imageUrl, BaseBitmapDataSubscriber mDataSubscriber) {
ImageRequest imageRequest = ImageRequestBuilder
.newBuilderWithSource(Uri.parse(imageUrl))
.setProgressiveRenderingEnabled(true)
.build();
ImagePipeline imagePipeline = Fresco.getImagePipeline();
DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage
(imageRequest, HiMicApplication.getInstance());
dataSource.subscribe(mDataSubscriber, CallerThreadExecutor.getInstance());
}
/**
* 图片拷贝
*
* @param imgUrl
* @param newPath
* @param fileName
* @return
*/
public static boolean copyPicFile(String imgUrl, String newPath, String fileName) {
FileBinaryResource fileBinaryResource = (FileBinaryResource) Fresco.getImagePipelineFactory()
.getMainFileCache().getResource(new SimpleCacheKey(imgUrl));
if (fileBinaryResource == null) {
return false;
}
File oldfile = fileBinaryResource.getFile();
boolean isok = true;
try {
int bytesum = 0;
int byteread = 0;
if (oldfile.exists()) { //文件存在时
InputStream inStream = new FileInputStream(oldfile); //读入原文件
if (!new File(newPath).exists()) {
new File(newPath).mkdirs();
}
String myPath = newPath + File.separator + fileName;
FileOutputStream fs = new FileOutputStream(myPath);
byte[] buffer = new byte[1024];
int length;
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread; //字节数 文件大小
fs.write(buffer, 0, byteread);
}
fs.flush();
fs.close();
inStream.close();
} else {
isok = false;
}
} catch (Exception e) {
isok = false;
}
return isok;
}
/**
* 加载 GIF 图
*
* @param url
* @param mSimpleDraweeView
*/
public static void loadImageGif(String url, SimpleDraweeView mSimpleDraweeView) {
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(Uri.parse(url))
.setAutoPlayAnimations(true)
.build();
mSimpleDraweeView.setController(controller);
}
/**
* 设置view大小。
* @param view View。
* @param width 指定宽。
* @param width 指定高。
*/
public static void requestLayout(View view, int width, int height) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
if (layoutParams == null) {
layoutParams = new ViewGroup.LayoutParams(width, height);
view.setLayoutParams(layoutParams);
} else {
view.getLayoutParams().width = width;
view.getLayoutParams().height = height;
view.requestLayout();
}
}
}
在proguard-rules.pro中加入
# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
-keep,allowobfuscation @interface com.facebook.soloader.DoNotOptimize
# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.common.internal.DoNotStrip *;
}
# Do not strip any method/class that is annotated with @DoNotOptimize
-keep @com.facebook.soloader.DoNotOptimize class *
-keepclassmembers class * {
@com.facebook.soloader.DoNotOptimize *;
}
# Keep native methods
-keepclassmembers class * {
native <methods>;
}
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**
-dontwarn com.facebook.infer.**
android {
splits {
abi {
enable true
reset()
include 'x86', 'x86_64', 'armeabi-v7a', 'armeabi'//不能保留arm64-v8a
//include 'armeabi-v7a'//或者只保留armeabi-v7a
universalApk false
}
}
}
解释:
enable: enables the ABIs split mechanism
exclude: By default all ABIs are included, you can remove some ABIs.
include: indicate which ABIs to be included
reset(): reset the list of ABIs to be included to an empty string (this allows, in conjunctions with include, to indicate which one to use rather than which ones to ignore)
universalApk: indicates whether to package a universal version (with all ABIs) or not. Default is false.