[Module] 07 - Libraries: Pros, Cons & Gotchas
安卓开发常用工具和第三方库汇总
From: https://academy.realm.io/cn/posts/tools-and-libraries-for-common-android-problems/
函数数量限制
- 在 Android 的世界中,我们必须考虑函数数量限制(64,000)。
- 有一个网站[函数数量]:http://methodscount.com
- 使用 ProGuard,许多库将会变得很小。
- Dex函数计数 会在你的 gradle 里,你也可以在你自己的编译系统上这么做,跟踪你应用程序中函数的总个数。
- Apk-method-count 是一个很棒的工具。
社交登录
firebase自带服务。
联网
- Retrofit【from Square,尽可能少做事情,他们试图让库严格地解决具体的问题,接口干净,是基于okhttp的封装】
- Volley。
- 还有 native HTML URL Connect(通常不推荐)。
- OkHttp:大举提升网络性能的功臣,已经在 Android 4.4 的 native 里面了。
网络调试
- Stetho: Facebook 开发的。
- HttpLoggingInterceptor:将拦截器添加到你的网络请求中,并将其打印在日志文件上。你也可以看到一些 JSON 文件。有一堆类似的东西都命名为 logging 拦截器。使用 Square 的标准 HTTP 日志记录可以让你更轻松地浏览,非常方便。
图片
- Picasso 较小,最新版本从 2,879 行缩小到 849 行。
- Glide 倾向于提供你想要的每个功能:它可以加载 GIF,也可以显示视频预览图像。
- 如果你正在加载图片,Picasso 比较合适。它更受欢迎:它有更多的文档,更多的支持。
- 如果你一直都有些奇怪的场景,你可以冒险使用 Glide。如果你的使用场景很标准,Picasso 是一个不错的选择
- Facebook 发布了一个神奇的库 Fresco,解决了 API 21 之前的所有版本的内存不足问题。如果你定位较低端的设备,你在旧设备上有更多的内存需求,我建议你使用 Fresco。除此之外,我会坚持 Picasso 和 Glide。
提示
扔出一堆关于图像的提示。
在列表中预取。预取下一个或两个图像一定会带来更好的体验。
Cloudinary 是一个很酷的托管服务,你可以以特定的分辨率请求图像。他们努力做到这点。但是,当你调整请求的图像大小时,你必须确保你没有通过请求类似的图像来破坏缓存(所以这里有个平衡)。
bigHeap:我们的一个的应用程序,使用了 bigHeap 后,内存崩溃降到原来的 1/4。 Google 不鼓励使用它,因为它关闭了在后台的其他应用程序,因此应用程序之间的切换并不是那么好。但在某些时候,这不是你的问题。垃圾回收也需要更长时间,你可以使用它来屏蔽内存问题(你不应该这么做)。一般来说,bigHeap 是好的。如果你去 Play Store,并且搜索 largeHeap,你可以下载一个很酷的应用程序,它会显示你手机上启用了 bigHeap 的应用程序。你会注意到现在几乎每个人都陷入了困境,并且正在使用 bigHeap。
LeakCanary
LeakCanary 是当今内存泄露的神器,它可以帮助你找到内存泄露的地方。当你将 LeakCanary 添加到应用程序中时,它会自动开始观察你的 activity 的内存泄漏。
工作原理:
作为你引用的任何对象的弱引用:
将其附加到你不再被引用的内容中。你把它放在 destroy 代码段。
然后它做垃圾回收。如果对象仍然存在,这就是内存泄漏,所以它知道什么对象依旧存在。
这里有个 view 的例子来做点简单说明。
-
- 你从底部开始(这就是泄露的东西)。我有 home fragment。 它被 pin grid fragment 引用 - pin grid fragment 是这个对象的父亲。
- 然后我们有这个奇怪的$ 0 - 它解释说,这是一个可运行的对象。对象内有一个处理程序包含一个 runnable。
这段代码(这不是我的),它是 Android 操作系统的,是处理程序的代码。处理程序有个 runnalbe 正在运行。我需要确保处理程序不再保留 runnable。在这种情况下,我可以在视图的 destroy 中清除所有的 runnable 和处理程序,这将修复这个内存泄漏。
WeakHandler
随机工具 WeakHandler,这使得处理程序引用都是弱引用。如果你触发一个垃圾回收,就可以回收它们。
它的缺点是可以被垃圾回收 - 如果你不希望它们被垃圾回收,那可能会出现意想不到的事情。值得注意的是,我遇到的大多数内存泄漏都是无效的,它通常是一个正在运行的 non-missed 的类持有外部类(这是最常见的地方)。对于你的内存泄漏,还需要一个 bug 分类的方法。没有什么比你手机上有 70 个内存泄漏, 而你不知道下一步该做什么更糟糕了。作为一个团队,弄清楚当我们发现内存泄漏时要做什么,总是一个好主意。
UI
我们都知道我们一直深陷泥潭。Activity 是旧标准。因为你想重用,所以有了 fragment。
但是最后我们用 fragment 把 UI 显示做的异常复杂。试试另一种方法,基于视图的架构,它更流行。
在基于视图的架构里,你有一个框架布局,而不用处理任何原生的 Android navigation 的东西,你可以用你想要的视图替换内部的框架布局里的任何东西。希望这能够解决 fragment 的复杂性。
fragment 已经被简化了,而且更新了版本,它们现在更加稳定,但是人们依旧争论着需要有基于视图的架构。如果我们遵循这个论点,我们应该看看一些库(图形的底部,看幻灯片)。
- 基于视图的架构
Mortar 和 Flow 完成基本的导航功能,但它们并不解决所有常见问题(例如屏幕上保存的状态)。

奉行着想毁灭世界上所有 Fragment 的信条,Square 大概在一年前介绍了两个全新的库: Flow 和 Mortar。
作为反 Fragment 教主,Square 还创造了许多很好的库:Dagger, Retrofit, Picasso, Otto, and so many more。
到了今天,标准的 Android 应用架构已经转变为由一小部分的 Activity 和 许多 Fragment 构成。
如果将 Activity 与 自定义 View结合在一起使用,说不定不需要 Fragment 就能让 Activity 实现跨平台使用的目标呢。
使用 Flow 和 Mortar库背后的关键目的就是探索这个问题,并得到确切的答案。
Conductor 正是为这些基于 View 的视图而生的,它创建了一个解决方案:比如保存状态,转换等等。
Scoop 来自 Lyft,是经过产品测试的基于视图架构的解决方案。它们不保存状态,所以 Lyft 无法保存状态。
From: https://www.jianshu.com/p/ec24d1b66d03
Screen: 在应用导航层次结构中的一个特殊存在,用来代表我们视图的对象
Blueprint: 应用中具有私有的 Dagger 模块的部分
Presenter: 一个 View 控制器对象
Custom Views: 通过 Java 代码定义的 View,当然,用 XML 定义也是很常见的
抛弃了对 MVC 模式的执念,这个架构在完成之后变得更像 MVP 模式。
这样巨大的转变使得新的架构需要关注如何处理应用在运行时配置信息改变的问题,例如:旋转。
在 MVC 模式中,我们的控制器(Activity 和 Fragment)会随着我们的 View 一起被杀死。
然而,在 MVP 模式中,我们只有 View 被杀死,又在需要它的时候重现它。
- 模型 视图 表示(MVP)
- 推荐的第一个库是 Mosby。 // <---- 好东西!
- Nucleus 也很类似。
- Mortar,作为 Mortar 和 Flow 的一部分,是它们早期的版本,它们越升级问题越多。
NimbleDroid
性能测试是个非标的工具。
帮助你意识到,有人做了一个改动,我们的启动时间变慢了,或者我们的关键流程慢了。如果性能是一个高优先级的目标,那么使用它是很有效的。
JSON
GSON,在 Android 上,GSON 更受欢迎
Jackson;
Moshi 是 Square 采用的库,跟 GSON 非常相似。
LoganSquare,解析性能高,更快,LoganSquare 是一个很好的选择
Flatbuffer,JSON 人类可读,Flatbuffer 不是;更快!使用起来比 JSON 更难,所以谨慎使用。
数据库 - SQL
SQLBrite、SQLDelight、GreenDAO、OrmLite、DBFlow 。
易用性是第一优先事项,然后再考虑是他们在性能上是不是会更好。
数据库 - NoSQL
与其他可比较的数据库不同,Realm 支持的文档非常多。这可以最终节省你大量的开发时间,而且无所谓数据库类型。
Google 推荐的另一种 NoSQL 方法是 LevelDB。
隐藏问题:
Realm 数据库需要特别注意的地方是它的大小
原因是它是一个本地库。对于每个芯片架构,它们在你的应用程序中都包含了 Realm 数据库的完整副本。
为了避免这种情况,你可以将此代码放入 Gradle(参见幻灯片中的代码),并为每个架构生成一个单独的 APK。
Native Lib - 它会显示些本机库,以便你可以看到你是否为你的 APK 下载了不适用于你手机的代码库。这样做会减少内存使用。
数据库 - 移动平台
- Firebase:脱机的话,Firebase 是事后补救;
- Realm: 有离线优先的优点。脱机的话,事先就设计好了,Realm 在许多方面都支持离线。许多应用程序几乎不需要在线行为。如果你正在考虑运行应用跟踪程序,我们希望同步我们的运行状态,而且我们希望所有功能都能完全脱机运行,之后在线工作也正常。Realm 就会脱颖而出。
Analytics
Firebase 曾经是一个实时数据库,然后 Google(混淆我们)开始使用一大堆叫做 Firebase 的工具。
Firebase Analytics 是所有 Firebase 工具的基础。Google 意识到 iOS 和 Android 开发人员正在解决同样的问题。他们正在使用第三方服务并且通过付费来解决所有这些问题。他们认为,我们可以使构建应用程序更加容易,而且构建应用程序更容易,赚的钱就更多。他们做了这些工具的竞品。
谷歌试图使分析工具成为所有的工具的基础。这样做的愿景是,如果你收到崩溃报告,看到你的分析数据,你可以按照崩溃的投资回报率给它们排序。
你的通知系统也参与其中,你可以发送通知给那些碰到最昂贵的崩溃的客户,并告诉他们一些免费的折扣。我们知道你即将购买,因为你是一个高价值的崩溃。
这是个很酷的愿景。还没有实现,实话实说。有些工作正常,有些还在开发中,这不是谷歌最高的优先级的任务。但是很多工具还是很好的(不如竞争对手的工具)。
Analytics 虽然是免费的,但是事件不受限制。没有太多的理由不使用它。
另一个流行的是 Google Analytics(分析)。它很容易地获得许多关于用户的基本信息。这是我看到的唯一一个提供很酷的行为流程图的工具,在那里你可以看到人们在你的事件之间切换。它还是有点过时了,其记录事件的风格比所有其他分析工具更旧。它也是免费的,Firebase 意在替换它。
A / B 测试
我个人认为 A / B 测试被过度宣传。通常它被用于慢速学习,以便你了解的更清楚,如果是简单的命名规则就不适用了,当然你可以将其投放到用户手里,你会发现,100 个用户的样本中,55% 偏好了这一选择。这就是你通常看到的 A / B 测试。
它很容易产生 Bug。基本上,A / B 测试中应用程序版本数是你应用程序中的 A / B 测试数加 2。如果你的应用程序中有 3 个 A / B 测试,那么就有 8 个不同版本应用程序一起工作。你可能没有测试各种不同版本的应用程序。有时候你可能会发现因为这些问题,往往会导致重要的决定不太容易做了。
我的解决方案是用户分析服务。 Mixpanel 具有非常好的 A / B 测试工具,而且和你的分析工具兼容。有许多工具用于 A / B 测试。我想说最有名的是 Optimizely 和 Apptomize。Optimizely 更适合网页(他们的价格都有点神秘)。他们帮助你提供不同的版本,告诉你这是一个比另一个有显著的更好的统计学差异的版本。
Firebase Remote Config 在技术上可以用来进行 A / B 测试。它不是用于 A / B 测试的。它是用来在不需要开发人员的更新的情况下,从服务器发送键值对的,但是这能让我们做 A / B 测试。你可以发送两个不同版本的键值对,然后你可以使用代码来决定要做什么。之后,你可以将其传递到你自己的分析界面,并找出解析它的方法。从某个角度说,如果你使用 Firebase 远程配置,你是在创造轮子。
你也可以使用 A / B 测试商店列表。这是值得尝试的,特别是你在不同的国家里测试。这是比较容易的,你可以在那里获得一些收获。
A/B测试的应用举例
崩溃报告
Crashlytics 趋势是最受欢迎的。这是 Twitter 的 Fabric Suite 或者说是现在的 Google Fabric Suite 的一部分。它是免费的,并为你提供一个非常好的,高级的,有组织的崩溃视图。你仍然需要自行排序和确定优先级。它有一些问题,很难搜索和查询。我看到人们联合使用 Bugsnag,这样查询和搜索会更好一点。 Bugsnag 是相当不错的,但它不是免费的。
Instabug 和 Telescope。Telescope 是个库。你把它放到 bug 里,作为第三方服务。这些库的优点不是监控 crash,而是让你在问题出现时,摇晃手机来报告问题。这样,当你的团队中的设计师看到错误时,他们不用在 JIRA 里提交 Bug,或者和别人说明所有的步骤然后让别人来报 bug,但是你仍然希望这些不是 crash 的 bug 也能被修复。有这么一个工具,所有的测试用户,alpha 用户,你公司的人,看到错误都能告诉你,这些问题需要修复。
推送通知
GCM 或现在的 Firebase Cloud Messaging
Firebase 和 Mixpanel(以及其他许多库)都可以用来发送通知。
Urban Airship 的推送通知特别专业
更轻松
Butter Knife
一个工具是 Butter Knife(@indVView)。它使你的代码更漂亮。你可以使用 @BindView 通过 ID 查找视图,而不必遍历所有的视图。
Zelezny
Zelezny,是一个Android Studio 插件。把它放进 Layout 中,它会自动生成 BindViews 和 OnClicks。如果你以前一直是手敲代码,它会节省点时间。最大的限制是 annotation 的处理会破坏增量编译。如果你有 Butter Knife,那么你可能会比没有 Butter Knife 时的增量编译慢些。对我个人而言,我喜欢所有的 annotation 处理工具,船已航行。我已经接受了 annotation 处理器打破我的增量编译的现实。我听说有人建议将它们全部放在同一个模块中可以解决这个问题。这是唯一的缺点,许多 annotation 处理都会有这个问题。也许有一天这个问题会被修复。 JRebel 声称一些特定版本的增量编译已经修复了。除此之外,Butter Knife 是最好的选择。
Hugo
Hugo 是个 Jake Wharton 的库(* 当我说 Jake Wharton,一半的时候是指 Square,它们是同一个意思*)。它是一个轻量级的库,你可以在方法之上执行 @Debug.Log,然后打印出该方法花费的时间,以及参数。它特别适用于现场性能记录。 “我需要缓存这个变量吗?它被调用太多了以至于变慢了吗?”你可以看到,“不,这只花了 10 毫秒,我应该把它放在一个后台线程上,或者花了不到一毫秒,我们不用担心这个”。它很容易纳入你的代码,并迅速获得相关数字。
Dart & Henson
Dart & Henson,你有 intents ;不需要使用键值映射,它给你应该有的值。它做了点 annotation 的映射来展示 intents 的值是什么。我更喜欢的另外一种理解方法是你正在调用的 activity 的静态 intents 。这样,你可以传入你想要的参数,这样就解决了神秘的键值对的问题。它使得代码更加紧密,这样可以防止错误。
Retrolambda
如果你喜欢 lambdas,你应该使用 Retrolambda。需要注意是它产生四种方法,而不是正常的匿名类。我认为使用 Retrolambda 会使得代码不易读,这是你必须做出明智决定的地方。
更困难(初期)
RxJava
RxJava,对于那些没有听说过的人来说,这个库的想法是,过去的代码从 A 点开始,到 B 点结束。但在 Android 世界中,移动开发世界中,这一切就都不一样了。 *你从 A 点开始。然后人们点击某些东西,所以你必须做些别的事情来响应。然后一个通知进来,你必须又做些事情。然后数据库请求出现了。Reactive 努力使你的代码能够对你的应用程序中的发生的事情做出反应,帮助你更好的组织它们,而且方便移动。
起初很难,因为它有一个学习曲线。如果你正在看代码,特别是对于没有接触过 RxJava 的人来说,会有许多不清楚的地方。最简单的就是网络。但是,如果你有几个标准的例子,你使用这些案例,并确保是最佳的做法,情况就会不一样了。当你开始拥有这些功能时,它们非常强大,你可以将其运用于应用程序中的任何地方,但是当你这样做的时候,每当雇用新的开发人员,你将不得不教会他们每个 activity 是怎么工作的,这需要很小心。
此外,它很容易用错。即使是关于 RxJava 的许多会议都会漏掉一些最佳做法。例如,如果你不取消订阅网络呼叫,那么你会被回调,这时可能会发生崩溃,因为屏幕已经不存在了。谨慎地使用它,总体上来说它还是很好的。
Kotlin
当我说小心使用非内建语言或者说新语言不寻常的地方时,我想说的就是那些你能看到的不寻常的地方。 Kotlin 生成了更整洁的代码。这有好处。使你的代码更容易阅读,也会使没有意义的东西少一些,这是你需要的核心东西。它也隐藏了指针的概念。
最大的缺点是它会随机地破坏事情,如果有什么事情发生,你都会怀疑 Kotlin。这可能是 Kotlin 的错,可能不是,但是都会花掉开发人员的许多时间,来弄清楚到底是不是 Kotlin 的错。你需要更新 Gradle 的构建,然而这依旧不奏效。这可能是 Kotlin 的错,也可能不是 Kotlin 的错,但是你都不得不重新检查 Kotlin。
同样的情况是,你的 Android Studio 也会随机崩溃,或者 ProGuard 不工作了,因为它去掉了一些 Kotlin 的类。这些事情经常发生,很难扭转。Kotlin 有很多权衡点。我们在代码中使用它。确实有一些问题,与此同时,了解 Kotlin 的人们的代码审查更快。对于不知道 Kotlin 的人来说,有一个学习的曲线。这是一个权衡。你必须自己决定。
相机
如果你曾经在 Android 中使用过 Camera,而且你采用的是原生的方案,这并不疯狂,你会发现有摄像头 one API 和摄像头 two API,而且摄像头 two API 没有比摄像头 one API 更好,如果你同时支持新旧设备,你必须使用摄像头 one API,除非你只打算在非常新的设备上正常运行。
我的第一个建议是,如果你有使用相机的场景,构建一个 intent。让其他人的相机应用来解决你的问题,如果这不是你的核心场景的话。
如果不是这种情况,有一个名为 Material Camera 的库,我以前 fork 过。你可以添加自己的外观。它帮助你创建相机。解决问题。但是当你按照本教程进行首次设置后,横向显示时,图片会颠倒,你不得不在每个手机上都进行测试,因为他们会以不同的方式安装相机。还有很多边界案例要考虑。Material Camera 是伟大的,它已经把这些情况都解决了。它也支持视频。这是视频模式。你可以改变它上面的 UI,效果很好。
再说一次,如果 Camera 是你非常核心的用例,那么你应该重新构建它,这只是个折衷的方案。
我使用的每个相机应用都有裁剪功能,这个功能很可怕。我不知道是什么原因。你试图剪裁,突然间你的视频被剪掉了中间部分。有一个很好的库叫做 “Android Crop”。它提供了一个非常简单的新的 activity 来完成剪裁。
全球思考
作为 Android 的开发人员,我们需要考虑到世界各地的所有开发者。如果你正在为世界各地的开发人员做些开发工作,有些事情你必须考虑,比如网络仿真:你希望能够在低质量网络上进行测试。Android 上做到这点比 iOS 难。仿真器技术可以提供本地仿真器 AVD,但通常情况下,我的经验是,如果你在模拟器上进行任何 3G 操作,没有应用工作正常。我的一些应用程序有时候能在 3G 上正常工作。
我知道的最成功的工具是 Charles 代理。你可以配置经过某个代理。这很容易设置。你可以告诉代理,下载速度应该是多快。但仍然有一个挑战,你需要知道网络可能有多快。比如说像巴西的 3G 网络,几乎是一个无意义的声明 - 3G 在巴西各处都不一样,在各地都是非常不同的。某些时候,你必须尝试找一些数字,选择一些数字。
外面有些资源,但是选择参数是挑选网络仿真最困难的部分之一。有一个名为 Augmented Traffic Control 工具,它来自 Facebook。它允许你连接到服务器或设置路由器,你可以设置配置文件 - 当你连接到路由器时,你的互联网应该有多快。如果你有非开发人员为你测试,他们仍然可以连接到这个 WiFi 网络并设置他们拥有的连接级别。产品经理和测试人员一般也应该考虑质量较差的网络。 ATC 服务器很好用。
我相信新的 Android O 暗示他们会有类似于 AutoFitTextView 的东西,但现在这只是一个库,只要文本对于文本框来说太大,文本就会缩小。如果你正在翻译德语,它的很多字母比英文还是要大一些,那么它会把它缩小到框中。这不是你的第一个翻译解决方案,但最好让它们缩小到文本框的大小,而不是填满整个屏幕并覆盖所有内容。它将调整你的文本大小(更改你的文本大小来适应),这是一个很好的安全的翻译。
YearClass 是 Facebook 的另一个库。它会告诉你,运行你产品的最新的手机生产年份是多少。如果我们说 2015 年是最高的年份,那你就不用关心 2016 年制作的手机上的一些特别的事情。从分析角度来说,这是最好的 - 比如这个崩溃是,发生在 Android OS Marshmallow 上,所有的手机都是低功耗的手机,有时候会发生这种情况。知道一下 crash 在不同年份的手机上的发生概率可以帮你对这个 crash 有更深的了解。
Connection 类是理解用户连接质量的一个非常好的工具(* 这是我在开始时推荐的封装样本类)。它对网络进行分类。不是分成 4G 3G,因为它们变化很大,它依据的是带宽,分为优秀,好,中度或差,或未知。它通过采样下载速度来分类。然后它会移动平均值。这样做的价值是,例如,你是一个显示许多图像的图像网站,你可能希望在较差的网络上降低图像质量,或着执行其他操作。预先知道带宽可以做许多事情。
最大的警告是它的抽样可能是不合时宜的。你能做的事情是让它们开始采样和停止采样。比如,当我打开应用程序时,开始采样,当我关闭应用程序时停止。它们做的事情是查看你下载的数据量,每秒刷新一次。如果用户将你的应用程序打开,并且没有进行任何操作,他们会认为你的网络慢的可怕。我们所做的是,你可以在网络调用或者图像调用的中间启动它,这样做的效果很好。除此之外,这个库对你的网络带宽了解的很准确。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律