Android现代开发推荐 | Android Showcase 2.0

Android现代开发推荐 | Android Showcase 2.0

Android Showcase是一个完整的Android应用程序示例,它使用了现代的Android应用程序开发方法,集成了流行的开发工具、库和代码检查工具,以及强大的测试框架和持续集成(CI)设置。该项目的主要重点是推广模块化、可扩展、可维护和可测试的架构,并结合了最佳的软件开发实践。即使这个应用程序看起来很简单,它包含了所有关键组件,为强大的大规模应用程序打下了基础。

该项目中采用的设计原则和架构选择非常适合更大的团队和更长的应用程序生命周期。这个应用程序不仅展示了功能,而且证明了良好结构化和编写的代码如何作为可扩展和可维护软件开发项目的稳定支柱。无论是新手还是有经验的开发者,都可以从这个项目中学到很多东西。

应用简介

Android Showcase是一个展示各种音乐专辑信息的简单应用程序,它通过使用Last.fm音乐平台API动态获取数据。该应用程序包含多个特性模块,其中包括以下屏幕:

  • 专辑列表屏幕(Album list screen):显示专辑列表
  • 专辑详细信息屏幕(Album detail screen):显示所选专辑的信息
  • 个人资料屏幕(Profile screen):目前是空白(WiP)
  • 收藏夹屏幕(Favourites screen):目前是空白(WiP)

这些屏幕旨在展示应用程序设计和架构的不同方面,以及如何将它们整合到一个完整的Android应用程序中。无论您是初学者还是有经验的开发者,都可以从这个应用程序中学到很多东西。

技术栈

该项目利用 Android 生态系统中的最佳实践和许多流行的库和工具。除非有很好的理由使用非稳定的依赖项,否则大多数库都是稳定版本。

  • 技术栈
    • 100% Kotlin
      • 协程 - 执行后台操作
      • Kotlin Flow - 跨越所有应用层的数据流,包括视图。
      • Kotlin 符号处理 - 启用编译器插件
      • Kotlin 序列化 - 解析 JSON
    • Retrofit - 网络通信
    • Jetpack
      • Compose - 现代、本地 UI 工具包
      • Navigation - 应用内导航
      • Lifecycle - 在生命周期状态更改时执行操作
      • ViewModel - 以生命周期感知的方式存储和管理与 UI 相关的数据
      • Room - 存储离线缓存
    • Koin - 依赖注入(依赖检索)
    • Coil - 图片加载库
    • Lottie - 动画库
  • 现代架构
    • Clean Architecture
    • 使用 Navigation 组件 的单一活动架构
    • MVVM + MVI(表示层)
    • Android 架构组件
      (ViewModel
      , Kotlin Flow
      , Navigation)
    • Android KTX - Jetpack Kotlin 扩展
  • UI
    • 响应式 UI
    • Jetpack Compose - 现代、本地 UI 工具包(用于 Fragment)
    • View Binding - 检索 XML 视图 ID
      (仅用于 NavHostActivity)
    • Material Design 3 - 应用设计系统,提供 UI 组件
    • 主题选择
      • 深色主题 - 应用程序的深色主题(Android 10+)
      • 动态主题 - 使用生成的基于壁纸的主题(Android 12+)
  • CI
    • GitHub Actions
    • 自动 PR 验证,包括测试、linter 和第三方在线工具
  • 测试
    • 单元测试(通过 android-junit5 使用 JUnit 5)- 测试单个类
    • Konsist - 测试代码约定和架构规则
    • UI 测试(Espresso)-
      测试用户界面(WiP)
    • Mockk - 模拟框架
    • Kluent - 断言框架
  • 静态分析工具(linter)
    • Ktlint - 验证代码格式
    • Detekt - 验证代码复杂度和代码气味
    • Android Lint - 验证 Android 平台使用情况
  • Gradle
    • Gradle Kotlin DSL - 定义构建脚本
    • 自定义任务
    • Gradle 插件
      • Android Gradle - 标准 Android 插件
      • Test Logger - 格式化测试日志
      • SafeArgs - 在导航目的地之间传递数据
      • Android-junit5 - 使用 JUnit 5 与 Android
    • 版本目录 - 定义依赖关系
    • 类型安全访问器
  • GitHub 引导
    • Renovate - 自动更新依赖项
    • Stale - 自动关闭陈旧的问题和拉取请求,这些问题和拉取请求在项目中容易积累
  • 其他工具
    • Charles Proxy - 在 debug 构建中启用网络流量嗅探。

模块化架构

我们使用模块化的方式来减少大型系统的复杂性。每个模块是一个独立的构建块,具有明确的目标。我们将每个特性看作是可重用的组件,类似于microservice或私有库。

采用模块化的代码库方法有以下好处:

  • 可重用性 - 可以共享代码并从相同的基础构建多个应用程序。应用程序应该是其特性的总和,其中特性被组织为单独的模块。
  • 关注点分离 - 每个模块都有明确的API。与特性相关的类位于不同的模块中,并且没有显式的模块依赖项不能引用它们。我们严格控制着哪些内容对代码库的其他部分公开。
  • 特性可以并行开发,例如由不同的团队
  • 每个特性可以独立于其他特性进行开发
  • 构建时间更快

模块类型和模块依赖关系

下面的图表展示了项目模块(Gradle 子项目)之间的依赖关系。

应用程序有三种类型的模块:

  • app 模块 - 这是主模块。它包含将多个模块连接在一起的代码(类、依赖注入设置、NavHostActivity等)和基本应用程序配置(Retrofit 配置、所需权限设置、自定义 Application 类等)。
  • feature_x 模块 - 最常见的模块类型,包含与给定特性相关的所有代码。可以在 feature 模块之间共享一些资源或代码(当前应用程序没有此类模块)。
  • feature_base 模块 - 特性模块依赖于它们以共享公共代码。

特性模块结构

我们采用 Clean Architecture 在模块级别实现 - 每个模块都包含自己一组 Clean Architecture 层:

注意,app 模块和 library_x 模块的结构与特性模块的结构稍有不同。

每个特性模块包含非层组件和3个具有不同责任集的层。

表示层

该层最接近用户在屏幕上看到的内容。

presentation 层结合了 MVVMMVI 模式:

  • MVVM - 使用 Jetpack 的 ViewModel 封装一个 common UI state。它通过可观察的状态持有者(Kotlin Flow)公开状态。
  • MVI - action 修改 common UI state 并通过 Kotlin Flow 向视图发出新的状态。

common state 是每个视图的单一真理来源。这种解决方案源于 单向数据流 和 Redux 原则。

这种方法有助于创建一致的状态。状态通过 collectAsUiStateWithLifecycle 方法收集。Flow 集合以受生命周期管理的方式进行,因此不会浪费资源。

状态使用 Immutable 注解标记,Jetpack Compose 使用该注解启用组合优化。

组件:

  • 视图(Fragment) - 观察通用视图状态(通过 Kotlin Flow)。Compose 将由 Kotlin Flow 发出的状态转换为应用程序 UI。将用户交互传递给 ViewModel。视图很难进行测试,因此应尽可能简单。
  • ViewModel - 向视图发出(通过 Kotlin Flow)视图状态的更改,并处理用户交互(这些视图模型不仅仅是POJO 类)。
  • ViewState - 单个视图的通用状态
  • StateTimeTravelDebugger - 记录操作和视图状态转换以便进行调试。
  • NavManager - 单例,用于在 NavHostActivity 内处理所有导航事件(而不是在每个视图内单独处理)。
领域层

这是应用程序的核心层。请注意,domain 层独立于其他任何层。这样可以使领域模型和业务逻辑独立于其他层。换句话说,对其他层的更改(例如更改数据库(data 层)或屏幕 UI(presentation 层))理想情况下不会影响 domain 层的任何代码更改。

组件:

  • UseCase - 包含业务逻辑
  • DomainModel - 定义应用程序中将使用的数据的核心结构。这是应用程序数据的真理来源。
  • Repository 接口 - 保持 domain 层独立于 data layer(依赖反转)。
数据层

包装应用程序数据。为 domain 层提供数据,例如从互联网检索数据并在设备离线时将数据缓存到磁盘缓存中。

组件:

  • Repository 将数据公开给 domain 层。根据应用程序结构和外部 API 的质量,存储库还可以合并、过滤和转换数据。这些操作旨在为 domain 层创建高质量的数据源。存储库(一个或多个)负责从 Data Source 中读取并构建领域模型,并接受要写入 Data Source 的领域模型。
  • Mapper - 将 data model 映射到 domain model(使 domain 层独立于 data 层)。

该应用程序有两个 Data Sources - Retrofit(用于网络访问)和 Room(用于访问设备持久存储的本地存储)。这些数据源可以被视为一个隐式子层。每个数据源由多个类组成:

  • Retrofit Service - 定义一组 API 端点
  • Retrofit Response Model - 定义给定端点的网络对象(数据的顶层模型包含 ApiModels
  • Retrofit Api Data Model - 定义网络对象(响应模型的子对象)
  • Room Database - 持久性数据库,用于存储应用程序数据
  • Room DAO - 与存储的数据进行交互
  • Room Entity - 存储对象的定义

Retrofit API Data ModelsRoom Entities 都包含注解,因此给定的框架了解如何解析数据为对象。

数据流

下图展示了当用户与“专辑列表界面”交互时的应用程序数据流:

依赖管理

使用 Gradle 版本目录 作为集中化的依赖管理,共享第三方依赖项坐标(分组、构件、版本)跨所有模块(Gradle 项目和子项目)。

所有依赖项都存储在 settings.gradle.kts 文件中(默认位置)。Gradle 版本目录包括几个主要部分:

  • [versions] - 声明可被所有依赖项引用的版本
  • [libraries] - 声明库坐标的别名
  • [bundles] - 声明依赖捆绑包(组)
  • [plugins] - 声明 Gradle 插件依赖项

每个特性模块都依赖于 feature_base 模块,因此依赖项在不需要在每个特性模块中显式添加的情况下共享。

该项目启用了 TYPESAFE_PROJECT_ACCESSORS 实验性 Gradle 功能,以生成类型安全的访问器,以引用其他项目。

// Before
implementation(project(":feature_album"))

// After
implementation(projects.featureAlbum)

灵感

以下是一些额外的资源。

快速参考表

  • Material Theme Builder - 生成动态材料主题并查看其实际效果
  • Compose Material 3 Components
    - 包含材料组件的列表
  • Core App Quality Checklist - 学习如何构建高质量应用程序
  • Android Ecosystem Cheat Sheet - 包含 200+ 最重要的工具的板
  • Kotlin Coroutines - Use Cases on Android -
    最流行的协程用途

Android 项目

其他高质量的项目将帮助您找到适用于您的项目的解决方案(随机顺序):

  • Compose Samples - 存储库包含一组个别的 Android Studio
  • Jetpack Compose Playground - 这是一个 Jetpack Compose 示例
    项目
  • Now Android - 完全使用 Kotlin 和 Jetpack Compose 构建的功能齐全的 Android 应用程序
  • WhatsApp Clone Compose - 使用 Jetpack Compose 和 Stream Chat SDK
    构建的 WhatsApp 克隆应用程序,用于帮助您了解 Android 中的 Compose
  • Iosched - Google IO 2019 和 2021 的官方 Android 应用程序
  • Android Architecture Blueprints v2 - 展示了各种 Android
    架构方法来开发 Android 应用程序
  • Github Browser Sample - 多个小项目,演示了 Android
    架构组件的使用
  • Clean Architecture Boilerplate - 用于 Android 的清晰
    架构
  • Roxie - common state 方法的坚实示例以及非常好的文档
  • Kotlin Android Template - 模板,可让您在几秒钟内创建预配置的 Android Kotlin 项目

项目地址

https://github.com/igorwojda/android-showcase

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/332365.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python数字图像处理基础(八)——harris角点检测、图像尺度空间、SIFT算法

目录 harris角点检测原理函数 图像尺度空间概念局部不变性局部不变特征SIFT算法 harris角点检测 原理 Harris 角点检测是一种用于在图像中检测角点的算法。角点是图像中局部区域的交叉点或者突出的特征点。Harris 角点检测算法旨在寻找图像中对于平移、旋转和尺度变化具有不变…

数据结构:链式栈

stack.h /* * 文件名称&#xff1a;stack.h * 创 建 者&#xff1a;cxy * 创建日期&#xff1a;2024年01月18日 * 描 述&#xff1a; */ #ifndef _STACK_H #define _STACK_H#include <stdio.h> #include <stdlib.h>typedef struct stack{int data…

FPGA物理引脚,原理(Pacakge and pinout)-认知3

画FPGA芯片引脚封装图&#xff08;原理&#xff09;&#xff0c;第一是参考开发板(根据一下描述了解总览&#xff09;&#xff0c;第二是研究Datasheet. ASCII Pinout File Zynq-7000 All Programmable SoC Packaging and Pinout(UG585) 1. Pacakge overview 1.1&#xff0…

爬虫案例—根据四大名著书名抓取并存储为文本文件

爬虫案例—根据四大名著书名抓取并存储为文本文件 诗词名句网&#xff1a;https://www.shicimingju.com 目标&#xff1a;输入四大名著的书名&#xff0c;抓取名著的全部内容&#xff0c;包括书名&#xff0c;作者&#xff0c;年代及各章节内容 诗词名句网主页如下图&#x…

ChatGPT Plus续费充值,到账延迟,如何申诉?

ChatGPT Plus充值总是到账延迟比较严重&#xff0c;一般多是通过充值链接代充值遇到&#xff0c;如果是账号登陆充值&#xff0c;是即时到账。但是有的客户不愿意提供账号密码&#xff0c;遇到延迟到账的情况如何解决呢&#xff1f;客户可按下面操作申诉&#xff0c;可快速到账…

Linux编译器--gcc和g++使用

gcc和g使用 一、gcc/g的作用1.1 预处理1.2 编译1.3 汇编1.4 链接 二、静态库和动态库三、make/Makefile3.1 make/Makefile3.2 依赖关系和依赖方法3.3 多文件编译3.4 make原理3.5 项目清理 四、linux下的第一个小程序-进度条4.1 行缓冲区的概念4.2 \r和\n4.3 进度条代码 一、gcc…

细讲Labview条件结构用法及易错点

本文讲解Labview条件结构的常用情景及易错点注意事项。帮助大家深刻理解并使用该结构&#xff0c;欢迎点赞关注加评论&#xff0c;有问题可以私聊或在下方评论区留言。 本文程序均附在文章结尾&#xff0c;可自行下载学习。 博主之前讲过Labview事件结构、For循环等的基础知识介…

SpringBoot连接远程服务器redis

SpringBoot连接远程服务器redis 1、指定redis配置启动 进入redis安装地址&#xff0c;我这里安装的是 /usr/local/src/redis-6.2.6 先copy一份配置文件 cp redis.conf redis.conf.bck然后修改配置文件信息 vim redis.conf bind 0.0.0.0 # 守护进程&#xff0c;修改为yes后即可…

Flutter中使用minio_new库

前言 在移动开发中&#xff0c;我们常常会遇到需要在App中处理文件上传和下载的需求。Minio是一个开源的对象存储服务&#xff0c;它兼容Amazon S3云存储服务接口&#xff0c;可以用于存储大规模非结构化的数据。 开始之前 在pubspec.yaml文件中添加minio_new库的依赖&#xf…

2023企业怎样抵御经济的不确定性?

在日益不确定的经济环境&#xff0c;继续业务照旧可能会超过陷入逆风的风险。要加入真正有复原力的企业行列&#xff0c;实现整个经济周期的增长&#xff0c;2023是时候发力业务创新&#xff1a;优化选择新的创新组合&#xff0c;洞察并发现新的创新机会&#xff0c;并发展新的…

Android Launcher3各启动场景源码分析

文章目录 一、概述二、开机启动Launcher2.1、开机启动Launcher流程图2.2、开机启动流程源码分析 三、短压Home键启动Launcher3.1、短压Home键启动Launcher流程图3.2、短压Home键启动Launcher源码分析 四、Launcher异常崩溃后的自启动4.1、Launcher异常崩溃后的自启动流程图4.2、…

C语言总结十三:程序环境和预处理详细总结

了解程序的运行环境可以让我们更加清楚的程序的底层运行的每一个步骤和过程&#xff0c;做到心中有数&#xff0c;预处理阶段是在预编译阶段完成&#xff0c;掌握常用的预处理命令语法&#xff0c;可以让我们正确的使用预处理命令&#xff0c;从而提高代码的开发能力和阅读别人…

在线扒站网PHP源码-在线扒站工具网站源码

源码介绍 这是一款在线的网站模板下载程序&#xff0c;也就是我们常说的扒站工具&#xff0c;利用它我们可以很轻松的将别人的网站模板样式下载下来&#xff0c;这样就可以大大提高我们编写前端的速度了&#xff01;注&#xff1a;扒取的任何站点不得用于商业、违法用途&#…

如何在CentOS 7 中基于OpenSSL 3.0 搭建Python 3.0 环境

1、OpenSSL 1.1 原因 [rootlocalhost ~]# openssl version OpenSSL 1.0.2k-fips 26 Jan 2017 [rootlocalhost ~]#通过执行openssl version可知Linux系统已经安装了OpenSSL&#xff0c;但该版本较低&#xff1b;Python 3 要求 OpenSSL版本不能低于1.1.1&#xff0c;否则安装P…

【02】mapbox js api加载arcgis切片服务

需求&#xff1a; 第三方的mapbox js api加载arcgis切片服务&#xff0c;同时叠加在mapbox自带底图上 效果图&#xff1a; 形如这种地址去加载&#xff1a; http://zjq2022.gis.com:8080/demo/loadmapbox.html arcgis切片服务参考链接思路&#xff1a;【01】mapbox js api加…

【Copula】最可能场景详解

基于Copula联合分布的最可能场景详解 最可能场景&#xff08;The most-likely scenario&#xff09;实例探讨参考 最可能场景&#xff08;The most-likely scenario&#xff09; 相应英文介绍原理介绍如下&#xff1a;&#xff08;出自论文J2020-Drought hazard transferabilit…

RTC讲解

RTC&#xff08;Real Time Clock&#xff09;实时时钟 RTC实时时钟本质上是一个独立的定时器。RTC模块拥有一组连续计数的32位无符号计数器&#xff0c;在相应软件配置下&#xff0c;可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC模块和时钟配…

基于XG24-EK2703A的BLE HID蓝牙键盘+鼠标复合设备功能开发(BLE+HID+FreeRTOS+Gecko SDK)

目录 项目介绍硬件介绍项目设计开发环境及工程参考总体流程图硬件基本配置应用初始化按键中断回调定时器回调按键响应任务蓝牙事件回调BLE HIDReport Map及报文键盘设备鼠标设备复合设备 发送字符串上/下滚动 功能展示项目总结 &#x1f449; 【Funpack3-1】基于XG24-EK2703A的…

网络端口映射和端口转发的区别和联系

目 录 一、端口映射技术 1.1 原理 1.2 应用场景 1、远程访问 2、游戏主机 3、文件共享 4、监控视频共享 二、端口转发技术 2.1 原理 2.2 应用场景 1、网络负载均衡 2、网络安全 3、网络代理 三、端口映射和转发的实现方法 3.1 路由器配置 3.2 网络防火墙 …

C Primer Plus 第6版 编程练习 chapter 16

文章目录 1. 第1题1.1 题目描述1.2 编程源码1.3 结果显示 2. 第2题2.1 题目描述2.2 编程源码2.3 结果显示 3. 第3题3.1 题目描述3.2 编程源码3.3 结果显示 4. 第4题4.1 题目描述4.2 编程源码4.3 结果显示 5. 第5题5.1 题目描述5.2 编程源码5.3 结果显示 6. 第6题6.1 题目描述6.…