とても辛い!Netflix Android クライアントのオープンソース ライブラリ

「ナゲッツ・スターティングプラン」に参加中です

少し前に「Netflixの自由と責任の労働法」という本を読んで以来、Netlifxという会社にとても良い印象を持っています。今日突然興味が湧いたのですが、このシリコンバレーのクールな企業は Android クライアントにどのようなオープン ソース ライブラリを使用しているのでしょうか? 一般に、外国企業はオープンソース ライブラリを選択する際に非常に慎重であり、複数回の比較と PK を経て決定する必要があります。ここで整理整頓を行い、ちなみに、将来同じようなニーズに遭遇したときに車輪の回転を繰り返さないように、頭の中で主流の認知を同期させてください。

確認方法

非常に簡単です。私の方法は、オープンソース契約を調べることです。ほとんどのオープン ソース ライブラリは、使用するオープン ソース ライブラリを宣言するため、参照者はこの情報をアプリの別のページに表示する必要があります。そのため、このページを表示することでどのサードパーティ ライブラリが接続されているかを確認でき、逆コンパイルの問題がなくなります。 。

私は8.69.0 build 12バージョン クライアントを使用しています。関連情報を次の図に示します。

画像.png

オープンソースライブラリのリスト

注: 次の表では、国内の開発者によく知られている低レベル (例libCurllibOpenSSL)、言語に偏ったライブラリ (例Kotlin、 、 )、およびオープン ソース ライブラリ(例、 ) のほとんどを削除しています。MySQLRxJavaRxKotlinRxKotlin

表はタイプ別にソートされています。また、公式の作成者がライブラリをアーカイブしない限り、それはアクティブであると考えられます。

静的なフォームではお好みのサイズで表示できない場合がありますので、オンライン フォームもご用意しました。

名前 住所 タイプ 説明する
丸みを帯びたイメージビュー github.com/vinc3m1/Rou… Androidインターフェースコンポーネント 廃止 さまざまな半径を実装するために使用される Circular ImageView
オートバリュー github.com/google/auto… Java 拡張機能 アクティブ アノテーションはコードを生成します。簡単に理解すると、data classKotlinを実行します。
ジャワの詩人 github.com/square/java… Java 拡張機能 アクティブ Square によって作成されたこのファイルは Java API を呼び出すことによって生成され.java、多くの Gradle プラグインはそれを使用してコンパイルの背後でコードを生成します。
紙パック github.com/grandstaish… Java 拡張機能 廃止 注釈はParcelableオブジェクトを生成しCREATORwriteToParcel(...)
自動廃棄 uber.github.io/AutoDispose… RxJava 拡張機能 アクティブ 自動的にRxJavaバインドされたフローが内部に実装され、scope自動化を実現します。dispose
リリンカー github.com/KeepSafe/Re… Android JNI 開発拡張機能 アクティブ API 23未満のAndroidバージョンでsoライブラリリンクが利用できない場合がある問題を解決
地震 github.com/square/seis… アンドロイドセンサー アクティブ Android スマートフォンの手ぶれ検出ライブラリ。スクエアにそんな事があるとは思いませんでした。
スティッキースクロールビュー github.com/amarjain07/… Androidインターフェースコンポーネント アクティブ リストをスライドするときにビューを上部に修正
弾む城の暗号 www.bouncycastle.org/ Java 拡張機能 アクティブ Java プラットフォーム用のオープンソースの軽量暗号化パッケージ。
ロッティ github.com/airbnb/lott… Androidインターフェースコンポーネント アクティブ 有名なアニメーションライブラリ
クロネット 開発者.android.com/codelabs/cr… Androidネットワークリクエスト アクティブ Chrome で使用されるモバイル ネットワーク ライブラリ。HTTP、HTTP/2、QUIC プロトコルをサポートします。Android および iOS プラットフォームをサポート
エクソプレイヤー github.com/google/ExoP… Android 音视频 活跃 知名视频播放库
groupie github.com/lisawray/gr… Android RecyclerView 扩展 活跃 方便 RecyclerView 显示复杂布局
rtl-viewpager github.com/duolingo/rt… Android ViewPager 扩展 过时 扩展了 ViewPager 部分功能,现已被 ViewPager2 代替
Epoxy github.com/airbnb/epox… Android RecyclerView 扩展 活跃 简化 RecyclerView 多 ViewType 场景下的开发
FlexboxLayout github.com/google/flex… Android 界面组件 活跃 Google 出品的一个在 Android 平台实现类似前端 Flex 布局的组件
RxDogTag github.com/uber/RxDogT… RxJava 扩展 活跃 不想在用 RxJava 时实现 onError 可以用这个,也方便检查错误在哪。
JaroWinklerSimilarity commons.apache.org/proper/comm… Java 扩展 活跃 字符串相似度比较算法
Mavericks github.com/airbnb/mave… Android 架构 活跃 之前叫 MvRx,airbnb 开源的一套著名Android App 响应式开发框架。
Bugsnag github.com/bugsnag/bug… Android 架构 活跃 崩溃手机,国内类似 bugly
Facebook Battery github.com/facebookinc… Android 架构 活跃 Facebook 出的一款方便检测应用耗电的 SDK
Checker Framework checkerframework.org/ Java 扩展 活跃 可以通过编写插件来扩展 Java 编译器的功能,比如增加一些类型检查
card-stack-view github.com/yuyakaido/C… Android 界面组件 活跃 滑动卡片组件,实现探探那种左滑 dis 右滑 like 的效果
Tape by Square github.com/square/tape Android 架构 活跃 一个轻快的,事务性的,基于文件的FIFO的库
Moshi github.com/square/mosh… Java 扩展 活跃 目前对 Kotlin 兼容最好的 Json 解析库

接下来,我将按照这些开源库的“类型”跟大家一起过一遍。

需要说明的是,这里面有些库我对它很熟悉,有些比较陌生,有些甚至让我觉得“原来已经有这样的库了”!

每个人的认知是不同的,我没见过的有可能反而是你最熟悉的,反之亦然,所以这部分主要还是偏向我自己的理解。如果你用过上面这些库,欢迎在下方评论区留言分享,而如果我的理解有误,也欢迎指出,我将不慎感激!

Android 界面控件类

image.png

这部分我最感兴趣的是 groupieEpoxy 这两个控件。

groupie 这个库,从用法上看有点像 Drakeet 大神早年写的 MultiType,用来解决 RecyclerView 里有很多不同 ViewType 的 item 需要显示的问题。

彼时 Google 还没有弄出 ConcatAdapter,大家面对这样的需求只能在 Adapter 里重写 getItemViewType,然后在 onBindViewHolder 里根据不同的 ViewType 调用不同的 ViewHolder

MultiType 的出现简化了这些步骤,它把列表的每一项称数据认为是一个 ItemData,对应的有一个 ItemView。它封装了一个 MultiTypeAdapter,这个 adapter 提供一个唯一接收数据的方法 setData(items: Items) 方法,Items 本质是一个 ArrayList<Object>,里面可以 add 一个个的 ItemData,同时提供一个 register() 方法,用来把 ItemDataItemView 的关系成对注册,最后把它设给 RecyclerViewadapter 即可。

groupie 从用法上看和 MultiType 应该类似,只不过它限定了每一个 ItemData 的写法,提供了 ItemBindableItem 很好地支持了后来出的 ViewBinding。有点英雄所见略同,又有点站在巨人肩膀上了的意思。虽然没有在项目里落地过,但是 MultiType 我们至今有一个项目还在使用,在这里 shout out to Drakeet 大神。

Epoxy 相对而言就复杂一些,不过也是为了解决 RecyclerView 构建复杂列表的。飞书文档团队之前写过一篇比较完整的介绍文章,大家可以参考,就不在此赘述了。

其它几个控件比较平常,在此略评一二:

Rounded Image View 这个库兴趣不大,现在主流的图片加载框架都可以在加载图片的时候去动态裁剪(Transform),在实际应用中也比写死 ImageView 要更灵活。事实上我平时很少鼓励大家去写自定义控件,因为基本上一写一个坑,我就敢说国内没有多少开发者是在写自定义控件的时候,会老老实实把旋屏、状态保存、自定义属性、无障碍、等各种情形处理好的,且不谈内存和性能方面的问题了。个人猜测 Netflix 引用这个控件估计也是历史原因,既然能用,也就懒得改了吧。

Sticky Scroll View 这个库也没什么好说的,列表滑动中固定某个头部已经有很多类似的实现了,这个控件是基于 View 嵌套和 ScrollView 的,而现在做列表大部分都是 RecyclerView 或者 CollapingToolbarLayout 了,后两者都可以比较完美实现类似的效果。

Lottie 很出名,也已经出来很久了,连 aosp 里的项目都在用,做简单的点线动画非常合适,不在此赘述了。

rtl-viewpager 是对老的 ViewPager 的扩展,现在大部分需求应该都可以结合 ViewPager2 来实现了。

FlexboxLayoutConstranitLayout 出现之前的产物,由于是 Google 亲生的所以迄今还在维护。我个人觉得现阶段的 App 需求应该没有 ConstranitLayout + MotionLayout 做不了的吧?当然了,还是要结合具体需求,如果团队内有对前端比较熟悉的小伙伴,或者贴近 Flex 布局的需求,可以考虑。

Android 工具类

image.png

这部分我比较感兴趣的是 SeismicCronet

Seismic 令我感兴趣的主要还是历史原因。它居然是 11 年前就开源的一个用来检测手机晃动的库,而且还是 Sqaure 出品,如果你也是第一次知道,或者写到现在都是自己做晃动检测的,请把 “Squaure 牛逼” 打在评论区。

Cronet 这个库我倒不陌生,原因是我一直有经常看 Android Developer 官网的习惯。在 Perform network operations overview 这一章,Google 很久之前就已经把 Cronet 给列出来了,只“可惜” Retrofit 做得太好了,不管是稳定性,扩展性,还是和 Kotlin 的兼容性都近乎完美,所以基本上大家提到网络请求就是后者。但是 Cronet 也有它自己的优势,就是 QUIC,这一块估计过半数的 App 用不到,所以也不好怪大家不知道了。

其它两个库就没什么好说的了。Relinker 国内只要有 so 库并且需要下沉低版本的 App 估计都在用吧?而 Exoplayer 就更不用说了,应该是音视频播放 App 的标配。

Java、Kotlin 扩展类

CleanShot 2023-05-25 at 20.34.51@2x.png

这部分我比较感兴趣的是 Auto DisposeJaroWinklerSimilarity ,而其它的几乎现在都有更好的替代。

AutoDispose 是由 Uber 公司开源的,没错,就是国外滴滴打车那个公司。要提它就先要看 RxDogTag 这个库,用它可以方便地管理和调试 RxJavaRxAndroid 中的错误和异常(话说 Uber 真的好喜欢 RxJava 的样子)。而 AutoDispose在它的基础上,可以让开发者更方便地管理 RxJava 的订阅关系,并且可以减少代码的复杂度和出错几率。

还记得大概从 2021 年开始,因为协程慢慢成熟,我确实没怎么用过 RxJava 了,但之前最开始学习的时候,确实被它的 onComplete() onError() 搞得死去活来,印象中光这两个还不够,好像还要写一个处理 ExceptionConsumer,总之确实很繁琐(当然这跟我当时的认知有关,请熟悉 RxJava 的小伙伴看到这里不要打我)。这个库看起来一定程度上解决了这个问题,就像它官网写的那样 AutoDispose is an RxJava 2+ tool for automatically binding the execution of RxJava streams to a provided scope via disposal/cancellation.,既可以偷懒,而且在数据流出错的时候还能使堆栈更加方便直观,单着两点我就觉得很值得一用了。我没有去细看源码,如果有在用的小伙伴,欢迎补充指正。

再说 JaroWinklerSimilarity,准确说它不是单独开源的,而是 Apache Commons 里面的,但是我真的是第一次听说这个算法,它可以比较两个字符串之间的相似度,个人感觉还是很有趣的。背后的原理即 Jaro-Winkler 相似度算法,这是一个字符级别的算法,可以用于任何语言的字符串比较,也包括中文,但是需要注意的是,由于 Jaro-Winkler 算法是基于字符级别的,因此如果拿来比较两串中文的话,需要对文本进行拆字处理,效果可能没有比较英文串时那么准确。

剩下几个库就简单点评一下:

AutoValue 是 Google 出品,但主要是一个 For Java 的库,在 Kotlin First 的前提下,可以完全被 data class 替代,这一点在官方文档里也有说明。

Paper Parcel 同样在 Kotlin First 的前提下,也已经可以使用官方的 kotlin-parcelize 来替代,简单方便。

Bouncy Castle Crypto 是一个 Java 实现的加解密库,跟 Netflix 用到的具体算法有关,这个不在此赘述了。

Checker Framework 是一个测试框架,在 Android 自动化测试中可以用于检测代码中的代码缺陷和错误,提高测试的覆盖率和可靠性。公司有自动化测试的团队,可以考虑接入这个框架。

Moshi 这个就更加不用说了,如果到现在还只知道 Gsonfastjson的 Android 开发者可以去面壁了。

Android 架构类

截屏2023-06-19 22.57.28.png

这部分我比较感兴趣的是 Maverickstape。 先说 Mavericks,这又是 Airbnb 开源的一个库,没错,大名鼎鼎 Lottie 动画框架也是他们出品的。

Mavericks 是一个 Android MVI 结构的开源框架,适用于需要构建复杂、高效、可维护的 Android 应用程序的场景,特别是在需要处理大量异步数据、网络请求和数据持久化的情况下。Mavericks 的核心在于它的三大件,MavericksStateMavericksViewModel, 和 MavericksView,再配合它独有的 onEach 还有 withState几乎就可以 cover 我们平时开发的大部分场景,并且能够简化代码,同时官方还提供了依赖用以方便地集成使用 ViewBinding 甚至Hilt

写到这里我突然想起这一个月来面试的不少同学,每次问题 App 架构,他们的回答总是,提到“数据驱动 UI 更新”就是 MVVM,提到“逻辑界面分离”就是 MVI。那么问题来了,如果我的应用是 MVI架构,但是我的数据需要关心大量的状态,并且这些状态又要驱动 UI 更新呢?很少有同学能够答好这个问题。

请看回上上个自然段,恭喜你遇到了,Mavericks 就是用来解决这一问题的最好框架!

これは比較的単純でTape、Square がオープンソース化したグループキュー関連の実装であり、主にFileObjectQueue、 、InMemoryObjectQueueObjectQueue4QueueFileつの実装が含まれます。キューについては特に言うことはありません。FIFOそれだけです。このライブラリの存在は、異なるメディアに基づいて実装されるLRU 算法DiskLruCacheMemoryLruCacheに少し似ています。

要約する

一般に、Netflix Android クライアント チームは、オープンソース ライブラリの選択において、依然として Square や Airbnb などの大手オープンソース メーカーの製品を好みます。私が認めなければならないのは、これらのオープンソース ライブラリのほとんどは広く使用されており、テストに耐えられるため、奇妙な問題が発生することはなく、ましてや一定期間が経過すると誰もメンテナンスしなくなるということです。

さらに、言語レベルであれ、アーキテクチャ レベルであれ、自分のチームは比較的早く主流の Android 開発テクノロジに追随しているが、MAD を実践するのはまだ非常に難しいということも誰もが感じたことがあると思います

「自主研究」という点では、国内の雰囲気と違ってKPIもなく、プロモーション重視のプログラムもなく、巨人の肩に乗れるので車輪の再発明をする必要がないのだと思います。 Netflix が実際にはそれ自体で何も書き込んでいないことは誰でもわかります。しかし、Netflix を視聴するときの快適さを考えると、おそらく音声とビデオの作品があるのではないかと思います。これは私の専門分野ではないのが残念ですが、研究パートナーがいる場合は、コメント欄に追加していただければ幸いです。

最後に、大企業病が彼らのチームにも存在していることがわかります。Netflix Android クライアントには、古くてメンテナンスされなくなったものがたくさんあります。あるいは、Google には、より優れた実装を備えた公式のオープンソース ライブラリがあります。しかし、クライアントは依然としてこれらの古いコードを保持しており、移行されていません。変更すべきではありません。」または「変更するのは厳しすぎます。」変化"。では、プロジェクトが大きくなると、世界中の企業がこのような問題に直面するというのは本当でしょうか?

以上。

おすすめ

転載: juejin.im/post/7246453307735392316