ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Connect You 开源联系人应用开发者指南:Jetpack Compose + Room 架构完整解析

Connect You 开源联系人应用开发者指南:Jetpack Compose + Room 架构完整解析 Connect You 开源联系人应用开发者指南Jetpack Compose Room 架构完整解析【免费下载链接】ConnectYouPrivacy focused contacts and SMS messenger app built with MD3项目地址: https://gitcode.com/gh_mirrors/co/ConnectYouConnect You 是一款注重隐私、基于 Material Design 3 的开源 Android 联系人管理 短信应用完整采用 Jetpack Compose 构建 UI、Room 管理本地数据。本文带你从目录结构到 Repository 层双数据源设计快速看懂这套 MVVM 架构是如何落地的。项目分层架构一览先看目录布局整个应用只有一个模块app但内部严格按照「数据层 → 领域层 → 表现层」三层组织位于 app/src/main/java/com/bnyro/contacts/ 下层目录职责表现层presentation/Compose 界面、ViewModel、可复用组件导航层navigation/路由定义与深链处理领域层domain/数据模型、枚举、Repository 接口数据层data/Room 数据库与 DAO工具层util/备份、权限、联系人工具类这种布局的好处是界面只依赖 ViewModelViewModel 只依赖 Repository 接口换数据源时界面代码零改动——这正是后文「双数据源」设计的价值所在。Room 数据库设计3 张表存下所有联系人数据核心数据库定义在 AppDatabase.kt当前版本为 8并声明了 2→3→4→5 与 6→7→8 的多段 AutoMigrationDatabase( entities [LocalContact::class, DbDataItem::class, SmsData::class], autoMigrations [ AutoMigration(2, 3), AutoMigration(3, 4), // ... ], version 8 ) abstract class AppDatabase : RoomDatabase()设计上有两个值得学习的点EAV 模式存属性联系人主表LocalContact只存姓名、机构、收藏位等固定字段手机号、邮箱、生日、备注等可变数量的属性统一放进DbDataItem表用category字段枚举 DataCategory.kt 中的 NUMBER / EMAIL / EVENT / NOTE…区分类型。这样新增一种属性类型不需要改表结构。AutoMigration 声明式升级版本升级只靠注解驱动数据库的完整演进历史可在 app/schemas/ 目录看到 2 到 8 共 7 个版本的 schema 快照 JSON方便做数据校验。Repository 双数据源本地库 vs 系统联系人这是全项目最有架构价值的部分。领域层定义了统一接口 ContactsRepository.ktinterface ContactsRepository { val label: String suspend fun createContact(contact: ContactData) suspend fun getContactList(): ListContactData // ... }两个实现各走一条完全不同的技术路线实现存储位置技术要点LocalContactsRepository.kt应用私有 Room 库头像存文件、属性存 DbDataItem 表DeviceContactsRepository.kt系统 ContactsContractContentProvider 批量操作 权限校验本地实现头像不进数据库而是以联系人 ID 命名写入filesDir/images目录见saveProfileImage避免了 Room 中大图片的性能问题。设备实现所有写入都通过ContentProviderOperation组装成批量操作再applyBatch并用RequiresPermission注解约束READ_CONTACTS/WRITE_CONTACTS权限。切换逻辑在 ViewModelContactsModel.kt 中通过contactsSource状态决定当前注入哪个实现UI 层对数据从哪来完全无感知。MVVM Compose 状态管理ViewModel 怎么做表现层每个屏幕对应一个ViewModelpresentation/screens/以联系人列表的 ContactsModel.kt 为例用mutableStateOf直接驱动 Compose 重组contactsSource by mutableStateOf(...)用户切换「本地 / 设备」来源时 UI 自动刷新。UI 状态用密封类建模列表状态 ContactListState.kt 定义Loading / Success / Error等形态界面只需when分发杜绝 null 判断散落各处的经典问题。并行加载初始化时通过asyncawaitAll并发拉取两个数据源配合Dispatchers.IO执行耗时 IO。无 Hilt手工依赖注入ViewModel 通过viewModelFactory { initializer { ... } }手动构造并传入两个 Repository保持轻量无注解处理器。导航与深链可序列化的路由对象路由定义在 NavRoutes.kt所有路由都是Serializable密封类参数直接作为类字段Serializable data class MessageThread( val address: String, val body: String? null ) : NavRoutes()它还内置了connectyou://message/号码这类深链navDeepLink允许从快捷方式或系统短信意图直接跳转到对应会话——导航配置见 NavContainer.kt。隐私优先的配套设计自动备份BackupWorker.kt 定时导出VcardHelper.kt 负责 vCard 导入导出ZipUtils.kt 打包并可选密码加密PasswordUtils.kt。本地短信收件箱MmsReceiver.kt 捕获短信/MMS 写入 Room 的SmsData表形成独立于系统短信应用的私有存档。生物识别BiometricAuthUtil.kt 为打开加密备份提供指纹/面容解锁。总结这套架构最值得抄作业的 3 个点接口先行Repository 接口放在 domain 层Room 与系统 ContentProvider 两种数据源对上层透明测试和扩展都容易。EAV 存属性用category value的通用表替代宽表新增联系人字段类型零 schema 变更。密封类建模 UI 状态 手动工厂注入不引入重量级 DI 框架仅用 Compose State 和 ViewModel 就实现了清晰的单向数据流。按「先读 ContactsRepository.kt 接口 → 再对比两个实现 → 最后看 ViewModel 如何消费」的顺序走一遍源码半天时间就能完整理解这个项目的架构脉络也为你自己的 Android 联系人/数据管理类应用提供了一套可直接参考的模板。【免费下载链接】ConnectYouPrivacy focused contacts and SMS messenger app built with MD3项目地址: https://gitcode.com/gh_mirrors/co/ConnectYou创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表