如何阅读源码,阅读源码的难点和方法分析

本文转载自知乎 IT小透明,已获得转载授权。

几次想阅读源码,但是每回都坚持不下去,毕竟读源码真的是一件很难得事情。随便一份源码,动辄几百个类,每个类几百行,没点毅力真的坚持不下来。当然,也有阅读方法的缘故。

直到我看到了一本书《通用源码阅读指导书》,感觉才找到了源码阅读的方法,也正是在这本书的指导下,我读完了第一份开源源码MyBatis。

1 意义与难点

这本书最开始讲了源码阅读的优点,作者总结了四点:

透彻地理解项目的实现原理
接触到成熟和先进的架构方案
学习到可靠与巧妙的实施技巧
发现自身知识盲点,提升自身知识储备
然后讲解了为什么阅读源码十分困难,作者总结原因为每一个优秀的工程项目都凝聚了众多开发者的缜密思维逻辑;每一个优秀的工程项目都经历了从雏形到成熟的曲折演化过程。最终,这些思维逻辑和演化过程都会投射和堆叠到源码上,使得源码阅读的过程是一个通过源码去逆推思维逻辑和演化过程的工作,因此十分困难。

2 源码选择

阅读源码的一个重要工作就是选择合适的源码,作者总结了选择源码的几个纬度:

项目的成熟度
项目的应用广度
项目的涉及面
项目的规模
并给出了每个纬度的评判指标。

3 源码阅读方法

选好源码项目之后,要做的就是阅读源码。

作者介绍了源码阅读的方法、技巧、经验。主要包括两个大的步骤:

项目初探
源码阅读
在项目初探环节,主要是通过断点运行项目࿰

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
注意:本项目使用android studio开发,eclipse可能无法使用。 豆芽的名字取自“Douban, Yet Another”的缩写和中文词语“豆芽”的拼音正好相同的巧合。 取名之后,我才得知豆瓣的 Windows Phone 客户端的名字也叫做“豆芽”。所以相对于豆瓣官方应用“一个叫‘豆瓣’的App”,也正好将这个应用称为“另一个叫豆芽的应用”了。 为什么要有豆芽? 直接访问豆瓣的所有人里,最普遍而一致的用法是围绕电影、电视、书、唱片、活动(我们叫做”条目”的东西)的评分评论、发现和讨论。我们会把和网站同步的评分评论作为一个起点和基础,在手机上重新构建围绕个人兴趣的发现和讨论。 一个叫“豆瓣”的App——豆瓣日志 豆瓣从来不是一个单一的网站,而对于豆瓣的用法自然不尽相同。使用豆瓣是为了获取信息,但信息的获取是基于条目和算法,还是基于友邻和人,这个问题在豆瓣的多次改版中大概一直悬而未决。 这次,一个叫“豆瓣”的应用选择的是基于条目的推荐。但我个人作为一个重度豆瓣用户,重视的却恰好是基于人的推荐,喜欢的是友邻间的鸡犬相闻,以及闲逛时从条目评论、广播、日记中发现新友邻的惊喜。正如我在某次“还我旧版”运动中听到的声音,“不管怎么改版,只要友邻们还在就好”,改版是豆瓣不断良好发展的必经之路,但这句话中对友邻的珍重又令我感受到了豆瓣最宝贵的特质。 豆瓣作为一个工具的价值可以通过条目很好体现,但豆瓣作为一个独一无二的社区,只能通过它独有的、克制的、以人为本的方式才能维系。作为一个普通但也深爱豆瓣的用户,我希望豆瓣在这个方向上也不要失落,因为一个只有工具属性的网站对我而言将再也没有这样的归属感。 我在这一点上与豆瓣应用有了不同的追求,并且恰好有一些这方面的能力,又恰好豆瓣提供了开放的 API,于是就想要将这个想法实现出来了。 选择开始豆芽这个项目,还有一个原因是我希望在豆瓣继续看到平台原生的设计。 豆瓣广播在几年前就已经是国内少有的几个 Android Design 的应用,这一点一直令我钦佩和喜爱。在豆瓣应用最开始的版本中,也曾有过 Material Design 的尝试,但随着和 iOS 风格设计的杂糅,逐渐显得不合时宜,以至于最终选择了完全的 iOS 风格。我对此一直感到有些遗憾,况且 Material Design 也是一款更加优秀的设计语言。所以,我希望实现未能见到的另一种可能性。 部分特性 Material Design 首页友邻广播 启动速度优化 界面动画 支持屏幕旋转 平板多列视图 支持使用 Custom Tabs 打开网页 支持切换长/短链接显示 关于名字 指导原则 豆芽的最终目标是为豆瓣中基于友邻的信息获取方式提供在移动端的便利。为了优雅地实现这个目标,豆芽将主要遵循以下的原则: 遵循 Material Design 规范,且指导思想优先于细节规定。 像素完美,但更注重以人为本。 实现精确,代码可以自我辩护。 行为合格,支持屏幕旋转和平板布局。 功能崇尚简约,不打扰用户。 行为默认值合理,且用户可调节。 积极表现豆瓣特性,如广播、友邻、豆邮等。 通过细节设计,提倡用心、考虑到他人的内容。 规则可以被打破,但前提是理解规则。 功能架构 豆芽的架构将与当前网站的设计十分类似。 你可能会问,难道豆芽只是要做一个豆瓣网站的移动端界面么?并非如此。豆芽的最终目标是为基于友邻的信息获取方式提供便利,所以架构设计也是为此服务。而架构与当前网页端设计基本相同,则是因为现在网页端正是一个符合这个目标的设计,并且与移动端的导航也可以很好地契合。 让我们详细地规划一下豆芽吧。 导航采用抽屉一级导航 选项卡二级导航的方式。工具栏上将显示全局的动作。 工具栏 提醒:所有类别的提醒,可以查看历史提醒 豆邮:用户间的邮件往来,希望鼓励郑重而非聊天。 搜索:立即访问想要的内容。 用户:点击后显示个人页面,相当于“我的豆瓣”。 首页 友邻广播:友邻互动、友邻推荐、系统定制的推荐。 九点:友邻的日记、博客文章等,有深度的内容。 一刻:全站范围的热门内容推荐。 同城:基于地理位置的内容。 线上活动:基于共同兴趣的内容。 书 分类浏览、首页推荐:入口,以及最有可能发现新内容的地方。 我:管理自己的书标记、创造内容。 动态:查看友邻的阅读动态,互动、获得推荐。 豆瓣猜:基于算法的推荐。 电影 类似书。 音乐 类似书。 设置:提供应用设置等。 在子页面设计中,豆芽将尽量鼓励长内容和用心的互动。因为我相信只有豆瓣值得这样尝试。 实现状况 我在最初的二十天内冲刺实现了应用的网络层、账户系统等基础架构,和查看友邻广播需要的大部分功能,大约 8000 行代码。 在接下来的八十天中,由于课业、其他事情和速度瓶颈,实现过程有所减慢。但是,应用的细节功能和界面交互都正在不断地被实现和优化。代码量达到了 14000 行,同时为此应用而写作的多个开源库的数千行代码并没有被计入。 此后项目经历了大型的重构,以适应代码复用和支持屏幕旋转的需求。在此之后,我得以实现了一个较为美观的个人资料页,并且对应用的许多细节进行了完善。 目前实现了原“豆瓣广播”应用的大部分功能。剩下的工作也正在继续进行中。 实现架构 数据层面 应用除了对少数内容进行缓存,其他内容均直接从网络获取。 基于 Android 账户系统提供用户账户和身份认证。 使用 Volley 及部分自定义增强处理网络请求。 使用 Gson 自动填充数据模型。 使用 Glide 加载图片。 使用 DiskLRUCache 及自定义增强对首页数据进行缓存。 使用 EventBus 同步不同页面间对象状态。 界面层面 使用 Support Library 中的 AppCompat、Design、CardView、RecyclerView 进行 Material Design 实现,在必要时引入/自己写作第三方库以实现部分界面元素和效果。 使用框架的 Shared Element Transition 实现在 Android 5.0 以上的界面过渡动画。 界面实现一般分为 Activity、Fragment、Adapter 三个模块,分别负责作为容器,发起请求、展示数据和用户交互,以及数据/交互绑定。 实现难点 网络请求 Volley 本身是一个不算十分完备的库,对于请求参数、重试、认证等方面都需要开发者自己实现。在豆芽中,应用对 Volley 进行了包装,增加了以上功能,并且尽力做到了通用,为之后 API 层建立提供了很多方便。 磁盘缓存 DiskLRUCache 是一个只实现了同步取写入的库,因此豆芽对其进行了包装,提供了异步写的 API,正确实现,提高了应用的响应速度。 状态同步 由于各个界面独自获取数据,数据本身与常规的 ContentProvider 机制中不同,是去中心化的,即可能遇到状态不同步的问题。 具体地说,即有可能用户在广播详情界面中点赞后,回到主界面列表视图,发现并未更新状态。 而豆芽解决方案则是使用 EventBus,在请求完成后通知所有界面刷新同一数据。 界面动画 Android 5.0 以上提供了 SharedElementTransition,然而默认情况下共享的界面元素在动画时却会被放置在其他界面元素之上,导致其突然越过 AppBar 或 StatusBar 的情况。 通过大量的文档阅读、源代码分析和调试,经过大约一周的时间,最终实现了较为理想的效果。 屏幕旋转 Android 在屏幕旋转时,会销毁视图和 Activity 并重建,此时如何保存视图状态和已加载的数据、正在进行的网络请求即是问题。 Android 对部分视图状态提供了自动保存恢复,而豆芽对于其他需要保存的状态则通过自定义的 onSaveViewState() 和 onRestoreViewState()。 对于数据,豆芽通过自定义的一个无界面的 RetainDataFragment 进行数据保留,并且接口十分简单易用。 同时,由于网络请求的异步特性,豆芽通过自定义的一个 RequestFragment 实现了网络请求在 Activity 重建期间的保留,并且能够在 Activity 重建完成后将请求前的状态和请求结果回调至新的 Activity。 平板适配 Android 本身的资源系统提供了对不同配置的很好支持,通过建立不同的资源文件,即可在手机和平板上使用不同的界面设定。 此外,由于采用了 RecyclerView,通过在运行时判断当前设备配置,可以动态给界面设置为 1、2、3 列视图,充分利用屏幕空间。 启动速度 Android 默认在冷启动应用进程至能够调用 Activity.onCreate() 前会加载应用主题中的背景作为预览,而默认背景是白色,与应用在上部拥有绿色 AppBar 的效果不相匹配。 为了生成适应于不同屏幕大小、系统版本的图片,我使用 bash 编写了一系列脚本,并实现了一个通用的模板化 SVG 格式,详情见 MaterialColdStart 和 AndroidSVGScripts。 经过自定义窗口背景和其他优化,应用在手机上已经可以达到立即启动的视觉效果。 派生开源库 为此项目诞生的五个开源库: MaterialColdStart,800 Stars MaterialProgressBar,500 Stars CustomTabsHelper,200 Stars MaterialEditText SystemUiHelper 第三方库 PhotoView Glide Gson ButterKnife DiskLruCache ThreeTenABP Volley EventBus CustomTabsHelper MaterialEditText MaterialProgressBar SystemUiHelper MaterialColdStart 构建 APK 文件可以在本项目的 Releases 中找到。 至于手动构建本项目的基本步骤: 创建 signing.properties: storeFile=YOUR_STORE_FILE storePassword= keyAlias= keyPassword= 执行 ./gradlew build。 使用 安装应用后,请安装 豆芽 API Key 设置向导 以设置 API Key。 暂时没有内置的更新渠道,请关注本项目的 Release。 请不要安装从不可靠的来源获取的 APK,以免泄漏您的用户名和密码。 本项目git地址:https://github.com/DreaminginCodeZH/Douya

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

架构师易哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值