Thunderbird for Android 特性模块架构全解析:Feature Modules 划分、API/Internal 拆分与扩展实践

发布时间:2026/9/23 3:15:08
Thunderbird for Android 特性模块架构全解析:Feature Modules 划分、API/Internal 拆分与扩展实践 移动开发企业应用【免费下载链接】thunderbird-androidThunderbird for Android – Open Source Email App for Android (fka K-9 Mail)项目地址https://gitcode.com/gh_mirrors/th/thunderbird-android点击查看免费下载Thunderbird for Android前身 K-9 Mail将整个应用拆分为多个特性模块Feature Modules每个模块封装一项独立功能并通过稳定的 API 契约相互协作。本文以 docs/architecture/feature-modules.md 为主线结合 ADR-0009、模块结构文档 以及仓库中的真实源码与 settings.gradle.kts系统讲解特性模块的划分方式、命名约定、依赖规则以及如何按照既有模式扩展全新功能模块。读完本文你将掌握 Thunderbird for Android 的模块化组织思路并能在实际开发中正确创建、拆分与集成新特性模块。一、特性模块架构总览Thunderbird for Android 项目的核心设计目标是多个 feature 模块各司其职通过明确定义的 API 相互调用最终由顶层应用模块组装成完整应用。项目根目录下的 feature 目录即特性模块的物理载体与之并列的还有core基础能力、legacy遗留代码、mail邮件协议、backend后端协议实现、library可复用库等模块层级。下图为项目文档给出的特性模块总览对应 docs/architecture/feature-modules.md 中的架构图从图中可以看出应用层功能被划分为两类核心特性账户与邮件主链路Account账户管理、Mail邮件处理与展示、Navigation应用导航 UI、Onboarding新用户引导配置与辅助能力Settings应用配置、Notification推送与提醒、Search内容检索、Widget桌面组件。这 8 个模块并非扁平铺开而是各自再向下拆分为更细粒度的子模块subfeatures从而在特性域内部实现更小的构建单元与更清晰的职责边界。特性模块开发最佳实践原文档给出了 10 条开发新特性模块或扩展现有模块时必须遵守的最佳实践它们是整个模块体系的宪法API-First DesignAPI 优先设计先定义清晰的公共接口再进行实现Single Responsibility单一职责每个特性模块只承担一个定义明确的职责Minimal Dependencies最小依赖尽量压缩特性模块之间的依赖Proper Layering合理分层每个特性内部遵循 Clean Architecture 原则Testability可测试性设计上保证特性可以独立、隔离地测试Documentation文档化记录每个特性模块的用途与用法Consistent Naming命名一致遵循既定的命名约定见下文Feature Flags特性开关使用特性开关实现渐进式发布与 A/B 测试Accessibility无障碍确保所有特性对所有用户可访问Internationalization国际化设计阶段就考虑多语言支持。这些原则共同保证在功能持续扩张的同时Thunderbird for Android 仍能保持整洁、模块化的架构。二、模块组织规则API / Internal 拆分与命名约定特性模块能拆得开、合得上的关键在于一套强制性的模块组织规则。这部分是 docs/architecture/module-structure.md 与 ADR-0009 的核心内容也是理解本文所有模块树的前提。API 模块对外契约api模块定义其他模块可以依赖的公共契约。它应当保持稳定、文档完善、极少变更且不含任何实现细节。API 模块通常包含公共接口定义模块能力的契约Repository、Use Case、Service 接口等数据模型属于公共 API 的实体DTO / 值对象常量与枚举跨模块共享的常量与枚举类型扩展函数扩展公共类型的工具函数导航定义导航路由与参数。命名约定为特性模块用feature:feature-name:api核心模块用core:core-name:api。例如 feature/account/api 就是一个典型的最小化 API 模块其 READMEfeature/account/api/README.md明确说明它刻意不包含邮件地址等特性化字段只提供强类型账户标识AccountId、极简Account接口仅含身份以及聚合视图用的UnifiedAccountId哨兵值val id AccountIdFactory.create() // 生成新的随机 AccountId val parsed AccountIdFactory.of(rawString) // 从持久化值解析 if (id.isUnified) { // 路由到统一视图/聚合服务而非具体仓库 } id.requireReal() // 在写路径上调用若为 unified ID 则抛出 IllegalStateException从源码结构看Mail、Calendar、Sync 等模块应当各自定义以AccountId为键的能力模型而不是把字段塞进 Account API——这正是API 模块保持最小面的实践样本。Internal 模块私有实现internal模块旧称impl依赖同域的api模块但不允许被其他模块依赖唯一例外是组装模块:app-common、:app-k9mail、:app-thunderbird。它承载接口的具体实现Repository、DataSource、Mapper、UseCase 实现特性内部的 UI 实现、ViewModel、UI 状态模型特性域内的依赖注入DI装配与工厂实验性、易变的实现细节。命名约定为feature:feature-name:internal/core:core-name:internal存在多个实现变体时用限定后缀区分如feature:feature-name:internal-variant原文档示例feature:account:internal-gmail、feature:account:internal-noop。[!NOTE] ADR-0009 指出历史上项目使用:impl后缀后统一更名为:internal以更准确地表达私有实现细节这一语义。迁移是渐进式的因此代码库中impl与internal两种命名会同时存在但所有新模块都应使用:internal。包名与可见性规则特性 API 包名net.thunderbird.feature.area[.subarea]例如net.thunderbird.feature.account.settings特性 internal 包名镜像 API 包结构并在末尾追加.internal段例如net.thunderbird.feature.account.settings.internal.data、…internal.domain多实现变体模块:…:internal-variant映射到包…internal.variant例如:feature:mail:message:export:internal-eml→net.thunderbird.feature.mail.message.export.internal.eml多维度变体使用internal.dimension.value如net.thunderbird.core.storage.internal.database.sqlite。严格可见性是 internal 模块最重要的纪律内部模块中的代码默认全部标记为 Kotlininternal可见性只有依赖注入Koin 模块或组装必需的部分才保持public。这样即使其他模块意外依赖了 internal 模块也无法直接触碰实现细节。Internal 模块内部的 Clean Architecture复杂的特性 internal 模块应遵循 Clean Architecture按三层组织UI 层Compose UI 组件、ViewModel、UI 状态管理Domain 层Use Case、领域模型、业务逻辑Data 层Repository、DataSource、数据映射Mapper。feature:account:internal ├── src/main/kotlin/net/thunderbird/feature/account/internal │ ├── data/ │ │ ├── repository/ │ │ ├── datasource/ │ │ └── mapper/ │ ├── domain/ │ │ ├── repository/ │ │ ├── entity/ │ │ └── usecase/ │ └── ui/ │ ├── AccountScreen.kt │ └── AccountViewModel.kt这一分层在仓库中随处可见例如 feature/account/oauth、feature/mail/message/reader 等目录均采用类似的 data / domain / ui 结构。其他模块类型Testing、Fake、Common除 api/internal 外模块化体系还定义了三种辅助模块类型Testing 模块feature:feature-name:testing提供测试工具、框架扩展、fixture 与自定义 matcher例如 feature/notification/testing、core/android/testingFake 模块feature:feature-name:fake提供简化、可控、确定性的替身实现与通用测试数据用于测试/开发/演示例如 feature/account/fake。Fake 模块只应包含最通用的数据与实现特定用例应写在具体测试中Common 模块feature:feature-name:common共享同域内多个相关模块使用的实现细节、工具与 UI 组件例如 feature/account/common。Common 模块中的非公共代码同样应使用internal可见性。三、核心特性模块详解下面逐一拆解 8 个核心特性模块的职责与子模块结构。所有模块树均直接继承自 docs/architecture/feature-modules.md并补充了与仓库实际目录的对应关系。3.1 Account 模块账户管理Account 模块管理电子邮件账户的全部方面设置、配置与认证。feature:account ├── feature:account:api ├── feature:account:internal ├── feature:account:setup │ ├── feature:account:setup:api │ └── feature:account:setup:internal ├── feature:account:settings │ ├── feature:account:settings:api │ └── feature:account:settings:internal ├── feature:account:server │ ├── feature:account:server:api │ ├── feature:account:server:internal │ ├── feature:account:server:certificate │ │ ├── feature:account:server:certificate:api │ │ └── feature:account:server:certificate:internal │ ├── feature:account:server:settings │ │ ├── feature:account:server:settings:api │ │ └── feature:account:server:settings:internal │ └── feature:account:server:validation │ ├── feature:account:server:validation:api │ └── feature:account:server:validation:internal ├── feature:account:auth │ ├── feature:account:auth:api │ ├── feature:account:auth:internal │ └── feature:account:auth:oauth │ ├── feature:account:auth:oauth:api │ └── feature:account:auth:oauth:internal └── feature:account:storage ├── feature:account:storage:api ├── feature:account:storage:internal └── feature:account:storage:legacy ├── feature:account:storage:legacy:api └── feature:account:storage:legacy:internal子功能说明API / Internal账户管理的核心公共接口与内部实现Setup设置向导新账户设置向导功能api暴露设置流程的公共接口internal提供具体实现Settings账户设置账户级设置管理Server服务器服务器配置与管理向下细分为三层——CertificateSSL 证书处理Settings服务器设置配置Validation服务器连接校验Auth认证认证功能其中OAuth提供 OAuth 专用认证实现Storage存储账户数据持久化其中Legacy是遗留存储实现。仓库对照feature:account域在 feature/account 目录中实际展开为api、avatar、common、core、edit、fake、oauth、profile、server、settings、setup、storage等子模块。其中server下确有三层子模块 certificate、settings、validation与文档树一一对应oauth即文档中的auth:oauth演化形态。所有模块均在 settings.gradle.kts 中以:feature:account:*前缀注册。3.2 Mail 模块邮件处理Mail 模块处理核心邮件功能消息展示、撰写与文件夹管理。feature:mail ├── feature:mail:api ├── feature:mail:internal ├── feature:mail:account │ ├── feature:mail:account:api │ └── feature:mail:account:internal ├── feature:mail:folder │ ├── feature:mail:folder:api │ └── feature:mail:folder:internal ├── feature:mail:compose │ ├── feature:mail:compose:api │ └── feature:mail:compose:internal └── feature:mail:message ├── feature:mail:message:api ├── feature:mail:message:internal ├── feature:mail:message:view │ ├── feature:mail:message:view:api │ └── feature:mail:message:view:internal └── feature:mail:message:list ├── feature:mail:message:list:api └── feature:mail:message:list:internal子功能说明API / Internal邮件功能的公共接口与内部实现Account邮件域专用的账户接口与实现邮件账户集成Folder邮件文件夹管理api定义文件夹操作接口internal提供实现Compose邮件撰写功能Message消息处理与展示细分为View单封邮件查看与List消息列表展示与交互。仓库对照在 feature/mail 目录下实际存在account、folder、message三个子域feature/mail/message 进一步展开为api、composer、export、list、reader。可以看出文档树中的compose对应仓库中的composer撰写器message:view对应message:reader阅读器并且额外演化出message:export邮件导出含impl-eml/internal-eml变体见 settings.gradle.kts 中的:feature:mail:message:export:impl-eml。这印证了文档树描述的是目标形态而代码库仍在持续演进。3.3 Navigation 模块与 Navigation Drawer 模块Navigation 模块属于核心 UI 层提供贯穿应用的导航基础设施core:ui:navigation其内部包含三部分职责Navigation核心导航接口与路由Route类型安全的路由定义NavigationExtensionCompose 专用导航扩展。在仓库中对应 core/ui/navigation 模块注册为:core:ui:navigation。导航放在 core 而非 feature这一设计表明导航是跨特性复用的基础设施因此归入 core 层这与依赖方向从 feature 流向 core的规则一致。Navigation Drawer 模块则提供主界面导航抽屉的 UI 组件含下拉式等变体feature:navigation:drawer ├── feature:navigation:drawer:api ├── feature:navigation:drawer:internal └── feature:navigation:drawer:dropdown ├── feature:navigation:drawer:dropdown:api └── feature:navigation:drawer:dropdown:internal子功能说明API / Internal抽屉核心接口与内部实现Dropdown下拉式导航实现。仓库对照见 feature/navigation/drawer包含api与dropdown两个子模块dropdown即文档中的下拉变体。3.4 Onboarding 模块新用户引导Onboarding 模块引导新用户完成初始设置流程。feature:onboarding ├── feature:onboarding:api ├── feature:onboarding:internal ├── feature:onboarding:main │ ├── feature:onboarding:main:api │ └── feature:onboarding:main:internal ├── feature:onboarding:welcome │ ├── feature:onboarding:welcome:api │ └── feature:onboarding:welcome:internal ├── feature:onboarding:permissions │ ├── feature:onboarding:permissions:api │ └── feature:onboarding:permissions:internal └── feature:onboarding:migration ├── feature:onboarding:migration:api ├── feature:onboarding:migration:internal ├── feature:onboarding:migration:thunderbird │ ├── feature:onboarding:migration:thunderbird:api │ └── feature:onboarding:migration:thunderbird:internal └── feature:onboarding:migration:noop ├── feature:onboarding:migration:noop:api └── feature:onboarding:migration:noop:internal子功能说明API / InternalOnboarding 核心公共接口与内部实现Main主引导流程Welcome欢迎页与初始用户体验Permissions权限请求处理Migration从其他应用迁移数据细分为ThunderbirdThunderbird 专属迁移实现与Noop供测试用的空操作实现。仓库对照feature/onboarding 目录包含main、migration、permissions、welcome四个子模块且migration下确有thunderbird与noop两种实现变体与文档树完全一致。Noop空操作实现是贯穿整个项目的经典模式——它让同一个 API 契约在测试/占位场景下拥有确定性行为这也在 feature/funding/noop、feature/telemetry/noop 等模块中反复出现。3.5 Settings 模块应用配置Settings 模块提供配置应用行为的接口。feature:settings ├── feature:settings:api ├── feature:settings:internal ├── feature:settings:import │ ├── feature:settings:import:api │ └── feature:settings:import:internal └── feature:settings:ui ├── feature:settings:ui:api └── feature:settings:ui:internal子功能说明API / Internal设置功能核心公共接口与内部实现Import设置导入功能如从旧版本或其他客户端导入配置UI设置界面组件。仓库对照当前 feature/settings 下实现的是import子模块注册为:feature:settings:import设置界面的通用组件实际沉淀在 core 层如 core/ui/setting含api、component、impl-dialog等体现了通用设置 UI 下沉 core、特性化设置在 feature的布局。3.6 Notification 模块通知与提醒Notification 模块处理新邮件与事件的推送通知和提醒。feature:notification ├── feature:notification:api ├── feature:notification:internal ├── feature:notification:email │ ├── feature:notification:email:api │ └── feature:notification:email:internal └── feature:notification:push ├── feature:notification:push:api └── feature:notification:push:internal子功能说明API / Internal通知核心公共接口与内部实现Email邮件专用通知处理Push推送通知处理。仓库对照当前 feature/notification 包含api、impl迁移前的 internal 命名、testing与docs且 feature/notification/README.md 详细描述了其命令模式架构。该模块是对API/Internal 分离原则的绝佳印证Client客户端ViewModel 构建Notification载荷并调用 InvokerInvokerNotificationSender/DefaultNotificationSender用工厂创建命令并执行Command命令封装NotificationNotificationNotifier暴露execute()Receiver接收者平台渲染代码SystemNotificationNotifier使用NotificationManagerInAppNotificationNotifier使用BroadcastReceiver。整个:feature:notification:api是 KMP 模块通知类型分为SystemNotification系统托盘需要POST_NOTIFICATIONS权限与InAppNotification应用内展示无需权限每种通知必须声明NotificationSeverity严重级别Fatal / Critical / Warning / Temporary / Information以驱动打扰程度与样式。这种接口稳定、实现可插拔、命令解耦的设计正是特性模块 API-First 思想的落地范本。3.7 Search 模块搜索Search 模块提供邮件与联系人搜索能力。feature:search ├── feature:search:api ├── feature:search:internal ├── feature:search:email │ ├── feature:search:email:api │ └── feature:search:email:internal ├── feature:search:contact │ ├── feature:search:contact:api │ └── feature:search:contact:internal └── feature:search:ui ├── feature:search:ui:api └── feature:search:ui:internal子功能说明API / Internal搜索功能核心公共接口与内部实现Email邮件搜索能力Contact联系人搜索能力UI搜索界面组件。仓库对照当前 feature/search 下仅有impl-legacy一个实现模块注册为:feature:search:impl-legacy说明搜索功能仍处于从遗留实现向新架构迁移的阶段——这与 ADR-0009 描述的渐进式迁移过程一致。文档树中的email、contact、ui子模块可视为规划中的目标拆分形态。3.8 Widget 模块桌面组件Widget 模块提供主屏幕小组件用于快速访问邮件功能。feature:widget ├── feature:widget:api ├── feature:widget:internal ├── feature:widget:message-list │ ├── feature:widget:message-list:api │ └── feature:widget:message-list:internal ├── feature:widget:message-list-glance │ ├── feature:widget:message-list-glance:api │ └── feature:widget:message-list-glance:internal ├── feature:widget:shortcut │ ├── feature:widget:shortcut:api │ └── feature:widget:shortcut:internal └── feature:widget:unread ├── feature:widget:unread:api └── feature:widget:unread:internal子功能说明API / InternalWidget 核心公共接口与内部实现Message List邮件列表组件Message List GlanceGlance 风格的可速览消息组件Shortcut应用快捷方式组件Unread未读消息计数组件。仓库对照feature/widget 目录下四个子模块message-list、message-list-glance、shortcut、unread与文档树一一对应注册为:feature:widget:*。以 feature/widget/message-list 为例其src/main/kotlin/app下包含组件实现res中提供了各语言环境下的布局与字符串资源AndroidManifest.xml声明了 AppWidgetProvider 注册信息——一个典型特性模块的完整落盘形态。四、支撑性特性模块除核心邮件功能外项目还包含若干支撑性特性模块它们通常规模更小、更聚焦同样遵循 api/internal 拆分settings.gradle.kts 中均有注册。4.1 Autodiscovery服务器设置自动发现Autodiscovery 模块自动检测邮件服务器设置子模块模块坐标职责APIfeature:autodiscovery:api公共接口Autoconfigfeature:autodiscovery:autoconfig自动配置逻辑Servicefeature:autodiscovery:service服务实现Demofeature:autodiscovery:demo演示实现仓库对照feature/autodiscovery 下api、autoconfig、service、demo四个子模块齐备其中autoconfig还带有独立的测试源集src/test说明该模块的核心解析逻辑如从 ISP 配置、MX 记录等渠道推断服务器参数受到较完善的单元测试保护。4.2 Funding应用内赞助Funding 模块处理应用内的资金赞助与捐赠选项子模块模块坐标职责APIfeature:funding:api公共接口Google Playfeature:funding:googleplayGoogle Play 计费集成Linkfeature:funding:link外部赞助链接处理Noopfeature:funding:noop空操作实现仓库对照feature/funding 下api、googleplay、link、noop齐备。这是一个多实现变体的典型场景正式版通过 Google Play Billing 或外部链接收款而 Noop 实现让调试/测试版本无需真实计费逻辑即可编译运行。4.3 Migration数据迁移Migration 模块处理不同邮件客户端之间的数据迁移子模块模块坐标职责Providerfeature:migration:provider迁移数据提供者QR Codefeature:migration:qrcode基于二维码的迁移Launcherfeature:migration:launcher迁移启动器其中launcher进一步拆分APIfeature:migration:launcher:api启动器接口Noopfeature:migration:launcher:noop空操作实现Thunderbirdfeature:migration:launcher:thunderbirdThunderbird 专属实现。仓库对照feature/migration 下launcher、provider、qrcode三子模块齐备qrcode是一个体量较大的模块feature/migration/qrcode 含大量 UI 资源与实现承担扫码迁移账户配置的完整流程。4.4 Telemetry遥测与分析Telemetry 模块处理使用统计与上报子模块模块坐标职责APIfeature:telemetry:api公共接口Noopfeature:telemetry:noop空操作实现Gleanfeature:telemetry:gleanMozilla Glean 集成仓库对照feature/telemetry 下api、noop、glean三子模块齐备。该模块同样展示多实现变体思想正式构建接入 Mozilla Glean 遥测框架而 Noop 实现用于关闭遥测的构建变体——两种实现共享同一 API 契约由组装模块app 层决定注入哪一个。这与 settings.gradle.kts 中对:feature:telemetry:*的注册一一对应。五、模块间依赖关系与依赖规则特性之间通过定义良好的 API 相互交互。文档给出了核心特性Account、Mail与潜在扩展Calendar、Appointments之间的关系图Gradle 依赖规则强约束ADR-0009 将这些关系落实为可被构建逻辑强制检查的硬性规则单向依赖模块之间不得循环依赖依赖图必须是有向无环图DAGAPI-Internal 分离其他模块只能声明对别的域:feature:*:api/:core:*:api的依赖跨域依赖:feature:*:internal或:core:*:internal被禁止契约绑定集中在组装模块契约与实现的绑定只发生在:app-common、:app-k9mail、:app-thunderbird三个组合模块中依赖方向依赖从 app 模块流向app-common再流向 feature最终流向 core 与 library高层模块不得反向依赖低层模块最小依赖每个模块只声明其必需的最小依赖集避免传递依赖与膨胀。[!IMPORTANT] 项目构建逻辑中内置了检查若某模块依赖了上述例外之外的:*:internal模块构建会直接失败。这保证了架构纪律不依赖开发者的自觉而是由工具强制兜底。从源码验证依赖方向在 settings.gradle.kts 中可以看到依赖方向的完整剖面App 模块:app-k9mail、:app-thunderbird作为入口组装模块:app-common承载跨应用共享的集成代码Feature 模块:feature:account:*、:feature:mail:*、:feature:widget:*、:feature:notification:*等全部以:feature:前缀注册Core 模块:core:ui:navigation、:core:common、:core:featureflag、:core:preference:*等为基础能力更低层:mail:*协议、:backend:*后端、:legacy:*遗留、:library:*、:ui-utils:*。这种分层注册方式与文档中的依赖图完全吻合特性模块只依赖 core 与其他特性的 api而绝不向上依赖 app 层。六、如何扩展新特性从理论示例到落地实践模块化架构的核心收益之一就是易于扩展。原文档给出两个理论示例展示按既有模式新增特性时应有的模块结构。示例一Calendar 特性日历一个 Calendar 特性可将日历功能与邮件集成feature:calendar ├── feature:calendar:api ├── feature:calendar:internal ├── feature:calendar:event │ ├── feature:calendar:event:api │ └── feature:calendar:event:internal └── feature:calendar:sync ├── feature:calendar:sync:api └── feature:calendar:sync:internal示例二Appointments 特性日程/预约一个 Appointments 特性可管理会议与预约feature:appointment ├── feature:appointment:api ├── feature:appointment:internal ├── feature:appointment:scheduler │ ├── feature:appointment:scheduler:api │ └── feature:appointment:scheduler:internal └── feature:appointment:notification ├── feature:appointment:notification:api └── feature:appointment:notification:internal新特性的标准落地步骤结合 module-structure.md 中的粒度指南与 ADR-0009 的迁移计划从零新增一个特性模块的推荐路径如下先在internal起步不确定是否稳定时先创建:feature:name:internal等到确实需要对外共享且契约稳定后再提升到apiWhen in doubt, prefer starting in internal按需拆分子模块当功能域内部出现明显的职责边界如 Calendar 的 event 与 sync时按:feature:name:subarea:api|internal拆分在 settings.gradle.kts 注册仿照现有include(:feature:xxx:api)写法将新模块加入构建包名遵循net.thunderbird.feature.area[.subarea][.internal...]规则internal 代码默认internal可见性在组装模块完成绑定在:app-common或 app 模块中用 Koin 将接口绑定到实现为复杂特性配置测试与 fake 模块测试替身独立成模块保持 API 消费者不被实现细节污染。模块粒度的判断标准何时新建模块、何时拆分、何时合并module-structure.md 给出了明确指引新建模块功能边界清晰且可能被多个特性/应用复用、拆分可改善构建性能与可测试性时拆分模块模块超过约 1 万行、职责过多、依赖过多、构建时间过长时保持不拆功能高度内聚、规模小、职责单一时。七、总结Thunderbird for Android 的特性模块体系可以用一句话概括以 api/internal 拆分为骨架以单向依赖为约束以组装模块为枢纽以多实现变体noop/fake/变体后缀应对现实差异。原文档 feature-modules.md 给出的 8 个核心特性模块与 4 个支撑模块在仓库 feature 目录、settings.gradle.kts 与 ADR-0009 中均可逐一对证文档树与现状之间的细微差异如impl/internal并存、compose/composer演化则真实反映了项目渐进式重构的进行时状态。对开发者而言这套体系提供的不仅是目录组织方式更是一套可执行的架构纪律新特性先写契约、实现藏于 internal、依赖只走 api、绑定交给组装层。遵循这些规则任何新功能都能以低耦合、可测试、可独立演进的方式融入这个拥有两个应用Thunderbird 与 K-9 Mail的代码库。延伸阅读模块结构总览Module Structureapi/internal/测试/fake/common 各模块类型的详细规范ADR-0009Feature/Core API/Internal 拆分与依赖规则模块与包命名、Gradle 依赖强约束的权威来源架构总览Architecture模块类型、Clean Architecture 与跨切面关注点通知模块架构说明一个特性模块内部命令模式设计的完整案例账户 API 模块说明最小化 API 模块的实践样板赞分享移动开发企业应用【免费下载链接】thunderbird-androidThunderbird for Android – Open Source Email App for Android (fka K-9 Mail)项目地址https://gitcode.com/gh_mirrors/th/thunderbird-android点击查看免费下载相关推荐Thunderbird for Android 模块化架构规范Feature/Core API 与 Internal 拆分及依赖约束ADR-0009Thunderbird for Android 模块化架构规范Feature/Core API 与 Internal 拆分及依赖约束ADR 0009 导读移动开发企业应用Thunderbird for Android 模块化架构解析API 与 Internal 分离的黄金法则Thunderbird for Android 模块化架构解析API 与 Internal 分离的黄金法则 Thunderbird for Android前移动开发企业应用Thunderbird for Android 特性开关新架构声明式 Feature Flag Catalog 的设计与实践Thunderbird for Android 特性开关新架构声明式 Feature Flag Catalog 的设计与实践 导读 本文基于 Thunderb移动开发企业应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询