Fresco的实践历程
来源:互联网 发布:下载播放软件 编辑:程序博客网 时间:2024/05/20 18:00
此文章是记录我在项目中如何使用Fresco,以及遇到的问题,还有相对应的解决方案。
1.添加防盗链;
2.直接下载图片,不需要控件去调用;
3.如何实现既要求可以从相册选取,又可以直接网络下载的圆角图片;
一、Fresco集成以及使用方法的中文官网地址:点击打开链接
二、正常的操作流程我就不再赘述,我接下来主要介绍我们项目中遇到的问题。
1、由于我们公司对于图片安全要求比较严格,需要加防盗链,所以介绍Fresco添加防盗链的方法如下:
public static void initFresco(Context context) { ImagePipelineConfig config = OkHttpImagePipelineConfigFactory .newBuilder(context, getOkHttpClientForFresco()).build(); Fresco.initialize(context, config); } private static OkHttpClient getOkHttpClientForFresco() { OkHttpClient client; OkHttpClient.Builder builder = new OkHttpClient.Builder() .addInterceptor(new HeaderInterceptor()) .connectTimeout(20, TimeUnit.SECONDS); client = builder.build(); return client; } private static class HeaderInterceptor implements Interceptor { private HashMap<String, String> mHeadMap; private HeaderInterceptor() { mHeadMap = new HashMap<>(); } @Override public Response intercept(Chain chain) throws IOException, BaseException { Request request = chain.request(); Request.Builder builder = request.newBuilder(); for (String s : mHeadMap.keySet()) { builder.addHeader(s, mHeadMap.get(s)); } builder.addHeader("Referer", "xxxx"); builder.addHeader("Cookie", "xxx"); request = builder.build(); return chain.proceed(request); } }
2、由于之前我们用到的图片有圆角的,虽然Fresco官网提供了设置圆角的方法,但是这只是限于调用下载api的时候,我们所用到的场景是有时候需要从拍照获取,有时候需要从网络下载,所以这个设置圆角的api并不能满足所有的场景,于是我就将从拍照获取的Bitmap进行剪裁,剪裁成圆角图片,代码如下:
public static Bitmap getRoundRectBitmap(Bitmap bitmap, int radius) { Bitmap target = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), ARGB_8888); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); int bmWidth = target.getWidth(); int bmHeight = target.getHeight(); final Rect rect = new Rect(0, 0, bmWidth, bmHeight); final RectF rectF = new RectF(0, 0, bmWidth, bmHeight); Canvas canvas = new Canvas(target); paint.setXfermode(null); canvas.drawRoundRect(rectF, radius, radius, paint); paint.setXfermode(new PorterDuffXfermode(SRC_IN)); canvas.drawBitmap(bitmap, rect, rectF, paint); return target; }
3、Fresco是没有一个单独的api直接用于图片下载,而不需要控件调用的,需要自己去实现,解决办法如下:(ps:其中onGetFrescoImgListener是自己定义的一个interface,大家可以自行去修改)
/** * 根据url下载图片,返回字节数组 */ public static void frescoDownloadImg(@NonNull String url, @NonNull Activity context, @Nullable OnGetFrescoImgListener listener) { Uri uri = Uri.parse(url); ImagePipeline imagePipeline = Fresco.getImagePipeline(); ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(uri); ImageRequest imageRequest = builder.build(); // 获取未解码的图片数据 DataSource<CloseableReference<PooledByteBuffer>> dataSource = imagePipeline.fetchEncodedImage(imageRequest, context); dataSource.subscribe(new BaseDataSubscriber<CloseableReference<PooledByteBuffer>>() { private byte[][] data = new byte[1][1]; @Override public void onNewResultImpl(DataSource<CloseableReference<PooledByteBuffer>> dataSource) { if (!dataSource.isFinished()) { return; } CloseableReference<PooledByteBuffer> imageReference = dataSource.getResult(); if (imageReference != null) { final CloseableReference<PooledByteBuffer> closeableReference = imageReference.clone(); try { PooledByteBuffer pooledByteBuffer = closeableReference.get(); InputStream inputStream = new PooledByteBufferInputStream(pooledByteBuffer); data[0] = input2byte(inputStream); context.runOnUiThread(new Thread(() -> { if (listener != null) { listener.getFrescoImgByteSuccess(data[0]); } })); } catch (IOException e) { e.printStackTrace(); } finally { closeableReference.close(); } } } @Override public void onFailureImpl(DataSource dataSource) { context.runOnUiThread(new Thread(() -> { if (listener != null) { listener.getFrescoImgByteFail(data[0]); } })); } }, Executors.newSingleThreadExecutor()); }
public interface OnGetFrescoImgListener { void getFrescoImgByteSuccess(byte[] data); void getFrescoImgByteFail(byte[] data); }
使用方法如下:
/** * Fresco直接通过Url下载图片获取字节数组(异步) */ private void getBitmapFromUrl(String title, String link, String desc, String url, int flag) { FrescoUtil.frescoDownloadImg(url, (Activity) mContext, new FrescoUtil.OnGetFrescoImgListener() { @Override public void getFrescoImgByteSuccess(byte[] data) { startShareWechat(title, link, desc, data, flag); } @Override public void getFrescoImgByteFail(byte[] data) { startShareWechat(title, link, desc, data, flag); } }); }
4、接下来我贴一下我自己封装的FrescoUtil,还是个不怎么成熟的程序员,希望大家多多提建议,多多指教,接受批评和指正。
public class FrescoUtil { public static void initFresco(Context context) { ImagePipelineConfig config = OkHttpImagePipelineConfigFactory .newBuilder(context, getOkHttpClientForFresco()).build(); Fresco.initialize(context, config); } private static OkHttpClient getOkHttpClientForFresco() { OkHttpClient client; OkHttpClient.Builder builder = new OkHttpClient.Builder() .addInterceptor(new HeaderInterceptor()) .connectTimeout(20, TimeUnit.SECONDS); client = builder.build(); return client; } private static class HeaderInterceptor implements Interceptor { private HashMap<String, String> mHeadMap; private HeaderInterceptor() { mHeadMap = new HashMap<>(); } @Override public Response intercept(Chain chain) throws IOException, BaseException { Request request = chain.request(); Request.Builder builder = request.newBuilder(); for (String s : mHeadMap.keySet()) { builder.addHeader(s, mHeadMap.get(s)); } builder.addHeader("Referer", "xxx"); builder.addHeader("Cookie", "xxx"); request = builder.build(); return chain.proceed(request); } } public interface OnGetFrescoImgListener { void getFrescoImgByteSuccess(byte[] data); void getFrescoImgByteFail(byte[] data); } /** * SimpleDraweeView 加载 url */ public static void frescoSetImg(@NonNull SimpleDraweeView iv, String url) { iv.setImageURI(url); } /** * SimpleDraweeView 设置 GenericDraweeHierarchy 加载 url */ public static void frescoSetImg(@NonNull SimpleDraweeView iv, @NonNull GenericDraweeHierarchy hierarchy, String url) { iv.setHierarchy(hierarchy); iv.setImageURI(url); } /** * GenericDraweeHierarchy 设置 占位图、失败图,SimpleDraweeView 设置 GenericDraweeHierarchy 加载 url */ public static void frescoSetImg(@NonNull SimpleDraweeView iv, String url, int placeholderImageResId, int failureImageResId, @NonNull Context context) { frescoSetRoundImg(iv, url, placeholderImageResId, failureImageResId, null, null, context, null); } /** * GenericDraweeHierarchy 设置 占位图、占位图的何种比例缩放(可以传null)、失败图、失败图的何种比例缩放(可以传null),SimpleDraweeView 设置 * GenericDraweeHierarchy 加载 url */ public static void frescoSetImg(@NonNull SimpleDraweeView iv, String url, int placeholderImageResId, int failureImageResId, @Nullable ScalingUtils.ScaleType placeholderScale, @Nullable ScalingUtils.ScaleType failureImageScaleType, @NonNull Context context) { frescoSetRoundImg(iv, url, placeholderImageResId, failureImageResId, placeholderScale, failureImageScaleType, context, null); } /** * GenericDraweeHierarchy 设置 占位图、失败图,SimpleDraweeView 设置 GenericDraweeHierarchy 加载 url */ public static void frescoSetImg( @NonNull SimpleDraweeView iv, String url, int placeholderImageResId, int failureImageResId, @Nullable RoundingParams roundingParams, @NonNull Context context) { frescoSetRoundImg(iv, url, placeholderImageResId, failureImageResId, null, null, context, roundingParams); } /** * GenericDraweeHierarchy 设置 占位图、占位图的何种比例缩放、失败图、失败图的何种比例缩放、圆角设置,SimpleDraweeView 设置 * GenericDraweeHierarchy 加载 url */ public static void frescoSetRoundImg(@NonNull SimpleDraweeView iv, String url, int placeholderImageResId, int failureImageResId, @Nullable ScalingUtils.ScaleType placeholderScale, @Nullable ScalingUtils.ScaleType failureImageScaleType, @NonNull Context context, @Nullable RoundingParams roundingParams) { GenericDraweeHierarchy genericDraweeHierarchy = GenericDraweeHierarchyBuilder.newInstance(context.getResources()) .setPlaceholderImage(placeholderImageResId) .setFailureImage(failureImageResId) .setRoundingParams(roundingParams) .setPlaceholderImageScaleType(placeholderScale) .setFailureImageScaleType(failureImageScaleType) .build(); iv.setHierarchy(genericDraweeHierarchy); iv.setImageURI(url); } /** * 根据url下载图片,返回字节数组 */ public static void frescoDownloadImg(@NonNull String url, @NonNull Activity context, @Nullable OnGetFrescoImgListener listener) { Uri uri = Uri.parse(url); ImagePipeline imagePipeline = Fresco.getImagePipeline(); ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(uri); ImageRequest imageRequest = builder.build(); // 获取未解码的图片数据 DataSource<CloseableReference<PooledByteBuffer>> dataSource = imagePipeline.fetchEncodedImage(imageRequest, context); dataSource.subscribe(new BaseDataSubscriber<CloseableReference<PooledByteBuffer>>() { private byte[][] data = new byte[1][1]; @Override public void onNewResultImpl(DataSource<CloseableReference<PooledByteBuffer>> dataSource) { if (!dataSource.isFinished()) { return; } CloseableReference<PooledByteBuffer> imageReference = dataSource.getResult(); if (imageReference != null) { final CloseableReference<PooledByteBuffer> closeableReference = imageReference.clone(); try { PooledByteBuffer pooledByteBuffer = closeableReference.get(); InputStream inputStream = new PooledByteBufferInputStream(pooledByteBuffer); data[0] = input2byte(inputStream); context.runOnUiThread(new Thread(() -> { if (listener != null) { listener.getFrescoImgByteSuccess(data[0]); } })); } catch (IOException e) { e.printStackTrace(); } finally { closeableReference.close(); } } } @Override public void onFailureImpl(DataSource dataSource) { context.runOnUiThread(new Thread(() -> { if (listener != null) { listener.getFrescoImgByteFail(data[0]); } })); } }, Executors.newSingleThreadExecutor()); }
三、总结
虽然花费了一个星期的时间去替换了项目的图片第三方加载库,但是也只是限于解决了问题,我还是有点不求甚解,这种感觉很不好,我会在接下来的时间去认真的研究下这个Fresco的原理,以及各种实现的源码,然后有机会再出一篇专门的分析文章,这次就是记录下项目中遇到的问题以及解决方案,希望可以帮助到大家。
四、用后感
其实用起来感觉没有这么方便,各种方法封装的不够,但是换句话说,灵活性比较高,可以自己去搞,也有一方面是自己能力不足,希望以后自己越来越好。
阅读全文
1 0
- Fresco的实践历程
- Fresco实践总结
- Fresco实践之基础篇
- Fresco简单应用与实践
- 单点登录实践历程
- 记录kolla实践历程
- 科学的实践时代---1. 科学兴起的历程
- Android图片处理之Fresco初实践
- Fresco的使用
- Fresco的简单实用教程
- Fresco的简单使用
- Fresco的入门篇
- Fresco的相关
- Fresco的使用
- Fresco.initializeDrawee()的过程
- Fresco框架的介绍
- Fresco的初步使用
- Fresco的缓存机制
- 线段树2(区间更新)
- 每日一点Js(四)
- HDU6095-Rikka with Competition
- 线段树【模板】
- -fvisibility=hidden的用法
- Fresco的实践历程
- HashMap的四种访问方式
- 产品到平台的思考1
- HDU6106 Classes
- Linux下Vi用法
- 创建Java线程的3种方式及对比
- java GUI界面之JTable详解
- <C语言>如何一步一步根据简单的代码联想到更多的功能?(实现输入一个整数,输出比它小包括它本身的所有素数。)
- 对表格的增删改