多 Activity 多 Page 的 UI 架构

在古老的 Android 时代,基本上一个 Activity 就代表一个界面,所以开发不需要做选择,但随着技术的迭代与框架的完善,Fragment 的使用成为主流,再进化为 Jetpack 的 navigation。再到如今越来越火热的 Compose。同是 Android 开发,可能选择的技术栈已经完全不一致了,所以入门学者也容易眼花缭乱。

纯 Activity 时代

Activity 作为最基础的四大组件之一,使用相对简单:

  1. 在 AndroidManifest 注册
  2. 通过 startActivity 或者 startActivityForResult 启动,现在也可以通过 LauncherForActivityResult 来启动
  3. 通过 finish 结束 Activity

其主要的问题就是需要在 AndroidManifest 中注册,开发过程中容易忘记。若需要做 patch、插件化等功能,就必须搞一些 HolderActivity 预注册,也是相当麻烦的。

除此之外,它本身是一个很重的组件,启动一个 Activity 就会有跨进程的操作,比较耗时。除此之外,动画控制也不是那么的灵活。

Fragment 入场

Fragment 原本是为了给平板使用的,最简单的例子就是列表-详情,手机端是列表界面点击进入详情界面,而平板则可以左侧列表,右侧详情。

但随着 Fragment 的发展,因为其灵活性,它反而成了界面开发的主角,造就了单 Activity 多 Fragment 架构。

单 Activity 多 Fragment 架构。 Activity 就是一个承载 Fragment 的容器,所有的界面由 Fragment 承载,由于 Fragment 的事务型启动很繁琐,所以官方又出品了 Navigation 库来解决这个问题。但 Navigation 库需要创建并注册 Graph,也是一个繁琐的事情。

路由框架入场

Activity 与 Fragment/Navigation 的启动新界面的方式各不相同, Navigation 还有一个创建 Graph 的方式,代码编写极其繁琐,所以又诞生了统一接口的路由框架,其主要解决以下几个问题:

  1. 启动方式的大一统
  2. Navagation 注册表的代码自动生成
  3. 传参的大一统,Activity 使用 Intent添加参数, Fragment 使用 Bundle
  4. 跨 module 的界面启动(模块化需求)

由于官方没有出品,所以就是由各个业务职能部门创建,诸如:ARouter、TheRouter、QMUI Scheme、Emo Scheme 等库。

ARouter 与 TheRouter 偏向于模块化。

而个人开发的 QMUI Scheme 与 Emo Scheme 则没有支持模块化,而是在多 Activity 多 Page 的支持上花费了很大工费。这里一个 Page 可以是Fragment 也可以是 Compose。

多 Activity 多 Page 架构是指我们可以使用多个 Activity, 每个 Activity 都可以是多 Page 的存在, 具体是否要使用 Activity, 则由开发根据业务逻辑决定。

QMUI Scheme 支持了多 Activty 多 Fragment 架构。

Emo Scheme 支持了多 Activity 多 Compose 架构。

这是二者的差异,在 Emo Scheme 开发时,我觉得 Compose 诞生后,Fragment 就是一个鸡肋的存在了,所以现在我就完全抛弃它了。

那为何要采取多 Activity 多 Page 呢?

  1. 可以根据业务逻辑更好的做数据复用。举个例子,注册流程,可能分成数个界面,最中收集到全部数据,我的做法是用一个 RegActivity, 每一个环节用 RegUserNamePage、RegAvatarPage 等,数据放在 RegActivity 的 ViewModel 里供所有 Page 使用,就不用数据传来传去了。而注册成功后到新的 Activity, 销毁 RegActivity。
  2. 某些场景用单独的 Activity 更舒服:
    • 全屏。 如果会涉及全屏切换,那单独出一个 Activity 就更友好。因为我们设置全屏标志位是相对于 Activity 而言的。全屏界面跳转到非全屏界面,非全屏界面跳转全屏界面,如果用单 Activity 去维护,那是一件很痛苦的事情。
    • 需要用到 Activity 的 launchMode 的场景,例如播放器,需要 singleTask 之类的模式
    • 需要一次性销毁多个 Page 的情况,例如前面注册流程的例子,我注册过程中,用户可以返回到上一个 Page, 但是当注册完成后,那就直接销毁 RegActivity。
  3. 目前 Compose 里嵌套 WebView,Navigation 转场动画效果有点差,所以我是选择用 Activity 去承载。

总而言之,之所以把框架做得这么复杂,就是期望开发能够认真思考业务流程,要根据我们的业务流程认真的考虑我们该以什么样的容器去承载我们的界面更合适。选择正确,往往能取到事半功倍的效果。

目前而言,Emo Scheme 是所有路由框架中对这一块中支持得最好的,具体使用方法可以前往 官网 了解。

最后

世上没有最好的架构,只有最适合自己的。UI 往往是变动最频繁的业务,所以了解各个组件的优缺点,根据业务逻辑去选用最适合的,才是高效开发的捷径。不管怎样,都是有无数坑点的,趋利避害才是 UI 的归宿。UI 最好的经验就是知道各个组件有什么坑点,如何避开。不然随便一个坑,就够开发加好一会儿班了。

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89

Android Framework底层原理篇:https://qr18.cn/AQpN4J

Android 车载篇:https://qr18.cn/F05ZCM

Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL

Android 音视频篇:https://qr18.cn/Ei3VPD

Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp

OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD

Kotlin 篇:https://qr18.cn/CdjtAF

Gradle 篇:https://qr18.cn/DzrmMB

Flutter 篇:https://qr18.cn/DIvKma

Android 八大知识体:https://qr18.cn/CyxarU

Android 核心笔记:https://qr21.cn/CaZQLo

Android 往年面试题锦:https://qr18.cn/CKV8OZ

2023年最新Android 面试题集:https://qr18.cn/CgxrRy

Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ

音视频面试题锦:https://qr18.cn/AcV6Ap

相关推荐
聪明的笨猪猪4 分钟前
企业知识库AI架构选型:落地导向的架构决策与组件清单
经验分享·面试·架构·embedding·数据库架构
Dawson Zhu1 小时前
Queen Planner深度解析:Agent竞争从模型时代进入系统时代
人工智能·语言模型·架构·aigc·agi
孟健2 小时前
我用 REA 逆向自己的 Electron 桌面端,扒出 178 个 IPC 通道后我反而放心了
架构·开源·ai编程
Oll Correct2 小时前
Adobe illustrator 案例十四:花元素标志草图绘制
笔记·ui·adobe·illustrator
Cosolar3 小时前
极简智库:快速搭建你的开源项目教程阅读平台,让 docs/ 目录被更多人看见
java·架构·github
Linye3 小时前
配了 3 套 AI 规则还打架?聊聊 Agent 信源仲裁与三层验真
人工智能·架构
阿杰m3 小时前
Android源码第十三章:Bluetooth——沿一次发现走到控制器
android
一条Go3 小时前
历史告警归档:为什么"删掉主库行"是最后一步
后端·架构·github
程序员敲笔记3 小时前
把 Ubuntu-22.04 从 C 盘搬到其他盘:小白操作手册
架构
booboosui3 小时前
派活给另一个 AI:前后两次文件夹快照,就是交付清单
android