fackbook的Fresco (FaceBook推出的Android图片加载库

  • 时间:
  • 浏览:0

保持简单的接口。Producer只一个叫做produceResults的妙招,其他妙招须要一个Consumer对象。反过来,Consumer一个onNewResult妙招。

使用Facebook的人都非常喜欢Stickers,可是它还须要以动画形式存储GIF和Web格式。可是支持那此格式,就须要面临新的挑战。可是每一个动画全版后该 由不止一张图片组成的,你须要解码每一张图片,存储在内存里,如可让显示出来。对于大其他的动画,把每一帧图片放上去去内存是不可行的。

当其他人意识到其他人都上能 了必要从前做的可是,其他人取得了突破。可是其他人只调用lockPixels而不调用对应的unlockPixels,都上能 了其他人就还须要在Java的堆内存底下创建一个内存安全的图像,如可让越多意味着UItcp连接加载缓慢。只须要几行c++代码,其他人就完美的正确处理了其他那此的疑问。

在Android设备底下,快速高效的显示图片是极为重要的。过去的几年里,其他人在如可高效的存储图像这方面遇到了其他那此的疑问。图片都上能 了来越多,如可让手机的内存却很小。每一个像素的R、G、B和alpha通道总相当于占用4byte的空间。可是手机的屏幕是41000*10000,都上能 了一张屏幕大小的图片就要占用1.5M的内存。手机的内存通常很小,一阵一阵是Android设备须要给各个应用分配内存。在其他设备上,分给Facebook App的内存仅仅有16MB。一张图片就要所处其内存的十分之一。

不幸的是,内存进行垃圾回收的过程正是那此的疑问所在。当内存进行垃圾回收时,内存不仅仅进行了垃圾回收,还把 Android 应用全版终止了。这也是用户在使用 App 时最常见的卡顿或短暂假死的意味着之一。这会让正在使用 App 的用户非常懊丧,如可让其他人可是会焦躁地滑动屏幕可是点击按钮,但 App 唯一的响应其他:在 App 恢复正常可是,请求用户耐心听候

所有的后台都用c++代码实现。其他人保持一份解码数据和元数据解析,如宽度和宽度。其他人引用技术数据,它允其他个Java端的Drawables并肩访问一个WebP图像。

其他人使用像从前的系统把Producer联系起来。假设其他人一个producer的工作是把类型I转化为类型O,都上能 了它看起来应该是其他样子:

经过底下的代码正确处理后,可清除的Bitmap会驻留在 Ashmem 堆中。不管所处那此,垃圾回收器全版后该 会自动回收那此 Bitmap。当 Android 绘制系统在渲染那此图片,Android 的系统库就会把那此 Bitmap 从 Ashmem 堆中抽取出来,而当渲染可是现在开始后,那此 Bitmap 又会被放回到从前的位置。可是一个被抽取的图片须要再绘制一次,系统仅仅须要把它再解码一次,其他操作非常更慢。

为了理解Facebook到底做了那此工作,在此可是其他人须要了解在Android还须要使用的堆内存之间的区别。Android中每个App的Java堆内存大小全版后该 被严格的限制的。每个对象全版后该 使用Java的new在堆内存实例化,这是内存中相对安全的一块区域。内存有垃圾回收机制,其他当App没哟使用内存的可是,系统就会自动把这块内存回收。

在Java中,异步代码历来全版后该 通过Future机制来执行的。在另外的tcp连接底下代码被提交执行,如可让一个类似Future的对象还须要检查执行的结果是全版后该 可是完成了。如可让,这只在假设都上能 了一种结果的情况汇报下行得通。在正确处理渐进的图像的可是,其他人希望还须要全版如可让连续的显示结果。

DraweeViews 的功能都上能 了来越多,但全版后该 至关重要的。其他人监听Android的View不再显示在屏幕上的系统事件。当图片失去屏幕的可是,DraweeView还须要告诉DraweeController关闭使用的图像资源。这还须要正确处理内存泄露。此外,可是它可是没哟屏幕范围内句子,控制器会告诉图片管道撤销网络请求。如可让,像Fackbook那样滚动一长串的图片的可是,越多频繁的网络请求。

那此规则还须要有效地正确处理内存泄漏,并让其他人在像Fackbook的Android客户端其他大型的Javatcp连接中享受Native内存管理和通信。

在移动设备上显示图片须要其他的步骤: 



几只优秀的开源库全版后该 按照其他顺序执行的,比如 Picasso,Universal Image Loader,Glide和 Volley等等。底下那此开源库为Android的发展做出了非常重要的贡献。其他人相信Fresco在几只重要方面会表现的更好。

其他人建立了AnimatedDrawable,一个强大的还须要呈现动画的Drawable,并肩支持GIF和WebP格式。AnimatedDrawable实现标准的Android Animatable接口,其他调用者还须要随意的启动可是停止动画。为了优化内存使用,可是图片足够小的可是,其他人就在内存底下缓存那此图片,如可让可是都上能 了来越多,其他人还须要更慢的解码那此图片。那此行为调用者是全版可控的。

当你的App内存溢出会所处那此呢?它当然会崩溃!其他人开发了一个库来正确处理其他那此的疑问,其他人叫它Fresco。它还须要管理使用到的图片和内存,从此App不再崩溃。

这听起来像一个完美的正确处理方案,如可让那此的疑问是Bitmap解码的操作是运行在UItcp连接的。Bitmap解码是非常消耗CPU资源的,当消耗过大后该 引起UI阻塞。可是其他意味着,其他Google不推荐使用其他底部形态。现在它们推荐使用另外一个底部形态——inBitmap。如可让其他底部形态直到Android3.0可是才被支持。即使是从前,其他底部形态也全版后该 非常有用,除非 App 里的所有图片大小都相同,这对Fackbook来说显然是不适用的。老是到4.4版本,其他限制才被移除了。但其他人须要的是越多 运行在 Android 2.3 - 最新版本中的通用正确处理方案。

其他其他人创建了Drawee。这是一个像MVC架构的图片显示框架。该模型被称为DraweeHierarchy。它被实现为Drawables的一个层,对于底层的图像而言,每一个曾全版后该 特定的功能——成像、层叠、渐变可是是放缩。

壁画是绘画技术,几只世纪以来老是受到世界各地其他人的欢迎。其他人其他伟大的艺术家使用其他名字,从意大利文艺复兴时期的大师拉斐尔到壁画艺术家斯里兰卡。其他人并全版后该 假装达到其他伟大的水平,其他人真的希望Android开发者能像其他人当初享受创建其他开源库的过程一样,非常享受的使用它。

在c++中,通常的正确处理方案是建立智能指针类,实现引用计数。那此须要利用到c++的语言底部形态——拷贝构造函数、赋值操作符和选者的析构函数。其他语法在Java之中不所处,可是垃圾回收器越多 正确处理其他切。其他其他人须要以一种妙招在Java中实现C++的那此保证机制。

Android有另外一种内存区域,叫做Ashmem。它操作起来更像Native堆,如可让全版后该 额外的系统调用。Android 在操作 Ashmem 堆时,会把该堆中存有数据的内存区域从 Ashmem 堆中抽取出来,而全版后该 把它释放掉,这是一种弱内存释放模式;被抽取出来的这次责内存都上能 了当系统真正须要更多的内存时(系统内存严重不足用)才会被释放。当 Android 把被抽取出来的这次责内存放回 Ashmem 堆,若果被抽取的内存空间都上能 了被释放,可是的数据就会恢复到相应的位置。

完成其他图像显示和操作繁复的工具库可是,其他人我想要把它分享到Android开发者社区。其他人很高兴的回应,从今天起,其他项目可是作为开源代码了!

通过那此努力,显示图片的辛苦操作一去不复返了。调用代码只须要实例化一个DraweeView,如可让指定一个URI和其他可选的参数就还须要了。剩下的一切后该 自动完成。开发人员不须要担心管理图像内存,或更新图像流。Fresco为其他人把一切都做了。

当一张图片从网络上下载下来可是,其他人想显示一张占位图。可是下载失败了,其他人就会显示一个错误标志。当图片加载完可是,其他人一个渐变动画。通过使用硬件加速,其他人还须要按比例放缩,可是是矩阵变加在其他人我想要的大小如可让渲染。其他人不老是按照图片的中心进行放缩,都上能 了其他人还须要本人定义放缩的聚焦点。其他可是,其他人想显示圆角甚至是圆形的图片。所有的那此操作都应该是更慢而平滑的。

Ashmem都上能 了被Java应用直接正确处理,如可让全版后该 其他例外,图片其他其中之一。当你创建一张都上能 了经过压缩的Bitmap的可是,Android的API允许你指定算不算可清除的。

欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术、开源库、软件派发、测试等文章

相比之下,Native堆是由C++tcp连接的new进行分配的。在Native堆底下有更多可用内存,App只被设备的物理可用内存限制,如可让都上能 了垃圾回收机制或其他东西拖后腿。如可让c++tcp连接员须要本人回收所分配的每一块内存,如可让就会造成内存泄露,最终意味着tcp连接崩溃。

这还须要使其他人把非常繁复的步骤串起来,并肩也还须要保持其他人逻辑的独立性。

其他人可是的实现是使用Android的View对象——时机到了,还须要使用ImageView替换出占位的View。其他操作是非常慢的。改变View会让Android强制刷新整个布局,当用户滑动的可是,这绝对全版有你看了了的效果。比较明智的做法是使用Android的Drawables,它还须要更慢的被替换。

在后台,每一个箱子底下都实现了一个叫做“生产者/消费者”的新框架。在其他那此的疑问是,其他人是从ReactiveX获取的灵感。其他人的系统拥有和RxJava类似的接口,如可让更加适合移动设备,如可让有内置的对Closeables的支持。

其他人创建了一个类去完成这件事。其中一个叫做“SharedReference”,它有addReference和deleteReference一个妙招,调用者调用时须要采取基类对象或让它在范围之外。一旦引用计数器归零,资源正确处理(Bitmap.recycle)就会所处。

其他人的不同之所处于把底下的那此步骤看作是管道,而不仅仅是加载器。每一个步骤和其他方面应该是尽可是独立的,把数据和参数传递进去,如可让产生一个输出,就都上能 了简单。它应该还须要做其他操作,不管是并行还是串行。其他操作都上能 了在底部形态条件下越多 执行。其他有特殊要求的在tcp连接上执行。除此之外,当其他人考虑改进图像的可是,所有的图片就会变得非常繁复。其他人在低网速情况汇报下使用Facebook,其他人我想要那本人越多 尽快的看了图片,甚至老是是在图片都上能 了全版下载完可是。

就像《蜘蛛侠》底下说的:“能力越强,责任越大。”可清除的 Bitmap 既越多被垃圾回收器回收,其他会被 Ashmem 内置的清除机制正确处理,这使得使用它们可是会造成内存泄露。其他其他人都上能 了靠本人啦。

对于底下提到的“解码操作致使 UI 假死”的那此的疑问,其他人找到了一种并肩使 UI 显示和内存管理都表现良好的正确处理妙招。可是其他人在 UI tcp连接进行渲染可是把被抽取的内存区域放回到从前的位置,并确保它再其他会被抽取,从前们就还须要把那此图片放上去去 Ashmem 里,并肩越多老是再次出现 UI 假死的那此的疑问。幸运的是,Android 的 NDK 中一个函数还须要完美地实现其他需求,名字叫做 AndroidBitmap_lockPixels。其他函数最初的目的其他:在调用 unlockPixels 再次抽取内存区域后被执行。

其他人的正确处理妙招是定义一个更广义的Future版本,叫做DataSource。它提供了一个订阅妙招,调用者须要传入一个DataSubscriber和Executor。DataSubscriber还须要从DataSource获取到正确处理中和正确处理完毕的结果,如可让提供了很简单的妙招来区分。可是其他人须要非常频繁的正确处理那此对象,其他须要一个明确的close调用,幸运的是,DataSource一种其他Closeable。

DraweeControllers通过管道的妙招连接到图像上——可是是其他的图片加载库——如可让正确处理后台的图片操作。其他人从管道接收事件并决定如可正确处理其他人。其他人控制DraweeHierarchy实际上的操作——无论是占位图片,错误条件或是完成的图片。

然而,很显然,让Java开发者去调用那此妙招是很容易出错的。Java语言其他为了正确处理做从前的事情的!其他SharedReference之上,其他人构建了CloseableReference类。它不仅实现了Java的Closeable接口,如可让也实现了Cloneable接口。它的构造器和clone()妙招会调用addReference(),而close()妙招会调用deleteReference()。其他Java开发者须要遵守下面两条简单的的规则: