神刀安全网

Android使用Fresco之下载图片(包括GIF图)

Fresco相信大家都不陌生,是个很不错的图片加载器
最近做的需求有查看大图保存图片,保存图片很简单,但是保存gif图就需要处理一下了。
之前google了好久,也没有找到靠谱的答案,(还是API看的不够仔细 ~)
原理在Fresco 数据源和数据订阅者
因为是查看大图的时候保存图片,所以其实没有必要非从网络去下载图片了,内存or磁盘中可能已经有缓存,再去网络下载,显然是浪费用户的流量,所以我是这样做的。。。

情况一:

如果你的应用只有静态图片,那么

DataSource> dataSource1 = imagePipeline.fetchDecodedImage(imageRequest, null); dataSource1.subscribe(newBaseBitmapDataSubscriber() { @Override protected voidonNewResultImpl(Bitmap bitmap) { //get bitmap  } @Override protected voidonFailureImpl(DataSource> dataSource) { } }, CallerThreadExecutor.getInstance());

情况二:

如果你的应用有静态图片也有动态图片(GIF)

DataSource> dataSource = imagePipeline.fetchEncodedImage(imageRequest, null); dataSource.subscribe(newBaseDataSubscriber>() { @Override protected voidonNewResultImpl(DataSource> dataSource) { if(!dataSource.isFinished()) { saveFail(); return; } CloseableReference ref = dataSource.getResult(); if(ref !=null) { try{ PooledByteBuffer result = ref.get(); InputStream is =newPooledByteBufferInputStream(result); try{ ByteArrayOutputStream bos =newByteArrayOutputStream(1000); byte[] b =new byte[1000]; intn; while((n = is.read(b)) != -1) { bos.write(b,0,n); } is.close(); bos.close(); savePic(url,bos.toByteArray());//通过byte文件头,判断是否是gif,再做相应的命名处理 }catch(Exception e) { }finally{ Closeables.closeQuietly(is); } }finally{ CloseableReference.closeSafely(ref); ref =null; } } } @Override protected voidonFailureImpl(DataSource> dataSource) { saveFail(); } },CallerThreadExecutor.getInstance());

总结

现在开源项目特别多,大家也都尽可能的不去重复造轮子,但是使用一个好的开源框架,最好还是了解一下源码的实现,这样在使用的过程中,遇到的任何问题,都有解释的依据。

  • 情况一中,对图片做了解码处理,如果不想要解码,直接使用情况二的方式也是可以的。

  • Android使用Fresco之下载图片(包括GIF图)
    null是什么鬼

    上图中的null是什么鬼
    其实是需要传递的是context但是我们看源码

Android使用Fresco之下载图片(包括GIF图)
simpleDraweeView.setImageURI(getImageUri(path)

发现我们在调用设置图片是,底层传递的就是null,所以为了避免我们的context被无法控制的第三方框架一直引用而引发内存泄露,我们这里还是不要把context传递过去了(毕竟不传,也没发现什么问题),至于为什么会有这个参数,还是要多看源码分析了。

  • 保存到系统相册的问题
    前面的保存,我们是保存到sd卡中我们自己的目录,但是如果要保存到系统相册,大部分使用的方式:
    File file =newFile(filePath); String uri =null; String systemFilepath = filePath; try{ uri = MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(),"",""); systemFilepath =getFilePathByContentResolver(context,Uri.parse(uri)); MediaScannerConnection.scanFile(context, newString[]{systemFilepath}, null, null); FileHelper.DataDir.deleteFileOrDir(file); returnsystemFilepath; }catch(Throwable e) { }

    这里有个问题,看源码

Android使用Fresco之下载图片(包括GIF图)
insertImage

系统默认存储的是jpeg格式,这样如果保存GIF图就悲剧了。。。
开始我是想,拿到系统相册路径,手动保存,但是有两个问题
1、系统相册路径如何获取(不同rom存储的位置都不一样)
2、自己保存,缩略图怎么生成(系统保存到相册的的insertImage默认会保存一份缩略图)
目前这块我还没找到更好的方式处理,找到后一定要记录下来。。。

好了,我去写代码了。。。

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Android使用Fresco之下载图片(包括GIF图)

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址