Facebook中国籍工程师讲述背后故事:为Android重新打造Facebook

【编者按】今天,Facebook发布了Android版本的原生应用。本文是Facebook工程师Frank Qixing Du @星河明远 今天在Facebook官方工程师博客上最新发表的日志。作为核心参与者和开发团队领导者,他在文中讲述了最新发布的Android版Facebook应用如何针对Android平台进行的开发和改进的考虑、细节及遇到的挑战。

正文如下:

在过去一年里,我们一直在努力使我们的移动app更快、更可靠、更易用。在过去的几个月,我们着手了一个针对iOS的主要的措施,并启动了iOS上Facebook的原生改写。在Android上,我们已有固定日期的发布周期,并一直在稳步推进,以期Facebook可以多平台上稳定运作。

今天,我们发布了新的Android版Facebook,此版本重写了原生代码以提高速度和性能。为了支持Facebook跨设备平台特有的复杂性,我们从半原生的编码切换到纯粹原生的编码,这让我们可以得以优化Facebook的用户体验,比如更快的加载速度、新用户界面、磁盘缓存等等。

我们用原生代码重建了Android版Facebook的几个核心功能,这些功能包括新的订阅(Feed)和时间线(Timeline),无论是否打开app,你在浏览照片还是和朋友互动时,都能有更快的体验。现在,你可以更快的评论和“赞”一个故事,图片加载也更快了。我们也建立了一个自动更新的故事横幅来突出显示最新的故事,这样不管你在哪里,都能很快得看到。

我们也发现,在这个过程中,我们不得不找到新的方案和设想,来解决许多实际的挑战。

这些挑战包括:

a)减少无用单元收集:内存效率会显著影响UI的流畅。低效内存使用会导致大量无用单元收集,后者会导致多帧程序的停止和滚动时视觉上的不流畅。我们尤其专注最大程度得减少、排除或者推迟分配效率关键代码。我们也推迟运行分配沉重的代码(比如订阅源story解析)直至拖动停止和将它们从UI线程移除。

b)编写自定义事件总线:事件总线允许发布/订阅流,允许那些不该被察觉的类之间的通信或依赖于双方已经存在的通信。普通事件总线实现采用对象迭代器和反射,这会导致长时间的操作和和大量内存分配。为了解决这样的问题,我们执行了一个轻量级事件总线,它因可以避免所有的反射和对象迭代,所以可以在代码关键性能区域被注册和撤销注册,类似滚动”效果

c)将图片移至本机堆:加载图片是会占用大量内存的,高效加载和处理位图很有挑战性。直接在Jave堆上分配它们的标准方法会导致大量无用单元搜集和内存不足的错误。我们用BitmapFactory类中的inPurgeable flag在本机堆加载我们的位图。这让图片得以在本地内存分配而不是Java堆(Honeycomb and up),或者在被VM(Froyo/Gingerbread)追踪的外设内存中分配,这样可以很大程度得降低它们对我们分配甚至性能的影响。

d)写一个定制列表视图再循环器:视图循环利用可以加速strolling性能。常备的Android列表视图支持视图循环利用,但它对于行高非常不同的列元素效率不高,比如在订阅中。我们写了一个定制视图再循环器,一旦沉重的内容视图被加到循环利用堆,它会将这些沉重的内容视图分开。在更复杂的聚合订阅stories中,我们也能再循环利用substories.


展望:

这次新的发布为Android版Facebook应用的发展打下了坚实基础。此恰到好处的基础支持使我们可以持续让应用程序更快、更流畅,以及赋予其更丰富的功能。我们希望你喜欢我们的Android应用,用它记下值得回味的瞬间,分享你的故事,和你的家人、朋友共度美好假日。

订阅更多文章