android showcase,冷心为王/android-showcase

Android showcase

Kotlin-1.3.72-blue.svg

AGP-3.6.3-blue?style=flat

Gradle-5.6.4-blue?style=flat

7f632064-0be5-450f-b29f-f0e1460582ab

a7ef0746703e4c81b0e4af2c46e2885e

badge

Showcase is a sample project that presents a modern, 2020 approach to

Android application development with up to date tech-stack.

The goal of the project is to demonstrate best practices by using up to date tech-stack and presenting mod ern Android application

Architecture that is modular, scalable, maintainable, and testable. This application may look quite simple,

but it has all of these small details that will set the rock-solid foundation for the larger app suitable for bigger teams

and long application lifecycle.

This project is being maintained to match current industry standards. Please check CONTRIBUTING page if you want to help.

Project characteristics

This project brings to table set of best practices, tools, and solutions:

Modern architecture (dynamic feature modules, Clean Architecture, Model-View-ViewModel, Model-View-Intent)

A single-activity architecture (Navigation component)

Reactive UI

CI pipeline (GitHub Actions)

Testing (Unit, UI)

Static analysis tools

Dependency Injection

Material design

Tech-stack

application_anim.gif

Min API level is set to 21, so the presented approach is suitable for over

85% of devices running Android. This project takes advantage of many

popular libraries and tools of the Android ecosystem. Most of the libraries are in the stable version unless there is a

good reason to use non-stable dependency.

Tech-stack

Kotlin + Coroutines - perform background operations

Kodein - dependency injection

Retrofit - networking

Jetpack

Navigation - deal with whole in-app navigation

LiveData - notify views about database change

Lifecycle - perform an action when lifecycle state changes

ViewModel - store and manage UI-related data in a lifecycle conscious way

Coil - image loading library with Kotlin idiomatic API

Lottie - animation library

Stetho - application debugging tool

Architecture

Architecture

Feature related code is placed inside one of the feature modules.

We can think about each feature as the equivalent of microservice or private library.

The modularized code-base approach provides few benefits:

better separation of concerns. Each module has a clear API., Feature related classes life in different modules and can't be referenced without explicit module dependency.

features can be developed in parallel eg. by different teams

each feature can be developed in isolation, independently from other features

faster compile time

Module types and module dependencies

This is a diagram present dependencies between project modules (Gradle sub-projects).

module_dependencies.png?raw=true

Note that due usage of Android dynamic-feature module dependencies are reversed (feature modules are depending on app module, not another way around).

We have three kinds of modules in the application:

app module - this is the main module. It contains code that wires multiple modules together (dependency injection setup, NavHostActivity, etc.) and fundamental application configuration (retrofit configuration, required permissions setup, custom application class, etc.).

helper modules

application-independent library_base module containing common code base that could be reused in other projects/applications (this code is not specific to this application) eg. base classes, utilities, custom delegates, extensions.

additional application-specific library_x modules that some of the features could depend on. This is helpful if you want to share some assets or code only between few feature modules (currently app has no such modules)

feature modules - the most common type of module containing all code related to a given feature.

Feature module structure

Clean architecture is the "core architecture" of the application, so each feature module contains own set of Clean architecture layers:

module_dependencies_layers.png?raw=true

Notice that app module and library_x modules structure differs a bit from feature module structure.

Each feature module contains non-layer components and 3 layers with distinct set of responsibilities.

feature_structure.png?raw=true

Presentation layer

This layer is closest to what the user sees on the screen. The presentation layer is a mix of MVVM (Jetpack ViewModel used to preserve data across activity restart) and

MVI (actions modify the common state of the view and then new state is edited to a view via LiveData to be rendered).

common state (for each view) approach derives from

Unidirectional Data Flow and Redux

principles.

Components:

View (Fragment) - presents data on the screen and pass user interactions to View Model. Views are hard to test, so they should be as simple as possible.

ViewModel - dispatches (through LiveData) state changes to the view and deals with user interactions (these view models are not simply POJO classes).

ViewState - common state for a single view

NavManager - singleton that facilitates handling all navigation events inside NavHostActivity (instead of separately, inside each view)

Domain layer

This is the core layer of the application. Notice that the domain layer is independent of any other layers. This allows to make domain models and business logic independent from other layers.

In other words, changes in other layers will have no effect on domain layer eg. changing database (data layer) or screen UI (presentation layer) ideally will not result in any code change withing domain layer.

Components:

UseCase - contains business logic

DomainModel - defies the core structure of the data that will be used within the application. This is the source of truth for application data.

Repository interface - required to keep the domain layer independent from the data layer (Dependency inversion).

Data layer

Manages application data and exposes these data sources as repositories to the domain layer. Typical responsibilities of this layer would be to retrieve data from the internet and optionally cache this data locally.

Components:

Repository is exposing data to the domain layer. Depending on application structure and quality of the external APIs repository can also merge, filter, and transform the data. The intention of

these operations is to create high-quality data source for the domain layer, not to perform any business logic (domain layer use case responsibility).

Mapper - maps data model to domain model (to keep domain layer independent from the data layer).

RetrofitService - defines a set of API endpoints.

DataModel - defines the structure of the data retrieved from the network and contains annotations, so Retrofit (Moshi) understands how to parse this network data (XML, JSON, Binary...) this data into objects.

Data flow

Below diagram presents application data flow when a user interacts with album list screen:

app_data_flow.png?raw=true

External dependencies

All the external dependencies (external libraries) are defined in the single place - Gradle buildSrc folder. This approach allows to easily

manage dependencies and use the same dependency version across all modules. Because each feature module depends on the app module

we can easily share all core dependencies without redefining them in each feature module.

Ci pipeline

CI pipeline verifies project correctness which each PR.

All of the tasks run in parallel:

These are all of the Gradle tasks that are GitHub Actions:

./gradlew lintDebug - runs Android lint

./gradlew detekt - runs detekt

./gradlew ktlintCheck - runs ktlint

./gradlew testDebugUnitTest - run unit tests

./gradlew connectedCheck - run UI tests

./gradlew :app:bundleDebug - create app bundle

Design decisions

Read related articles to have a better understanding of underlying design decisions and various trade-offs.

What this project does not cover?

The interface of the app utilizes some of the modern material design components, however, is deliberately kept simple to

focus on application architecture.

Upcoming improvements

Checklist of all upcoming enhancements.

Getting started

There are a few ways to open this project.

Android Studio

Android Studio -> File -> New -> From Version control -> Git

Enter https://github.com/igorwojda/android-showcase.git into URL field

Command-line + Android Studio

Run git clone https://github.com/igorwojda/android-showcase.git

Android Studio -> File -> Open

Inspiration

This is project is a sample, to inspire you and should handle most of the common cases, but please take a look at

additional resources.

Cheat sheet

Android Ecosystem Cheat Sheet - board containing 200+ most important tools

Android projects

Other high-quality projects will help you to find solutions that work for your project:

Iosched - official Android application from google IO 2019

Android Architecture Blueprints v2 - a showcase of various

Android architecture approaches

Android sunflower complete Jetpack sample covering all

libraries

GithubBrowserSample - multiple small projects

demonstrating usage of Android Architecture Components

Plaid - a showcase of Android material design

Clean Architecture boilerplate - contains nice

diagrams of Clean Architecture layers

Android samples - official Android samples repository

Roxie - solid example of common state approach together witch very good

documentation

Kotlin Android template - template that lets you create an Android/Kotlin project and be up and running in a few seconds.

Known issues

ktlint import-ordering rule conflicts with IDE default formatting rule, so it have to be disabled

False positive "Unused symbol" for a custom Android application class referenced in AndroidManifest.xml file (Issue)

False positive "Function can be private" (Issue)

Unit tests are running in IDE but fail after running gradle task because of missing Agrs class (Issue)

Contribute

Want to contribute? Check our Contributing docs.

Author

avatar.png

igorwojda?style=social

License

MIT License

Copyright (c) 2019 Igor Wojda

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and

associated documentation files (the "Software"), to deal in the Software without restriction, including

without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to

the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial

portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT

LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN

NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,

WHETHER IN AN ACTION OF TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE

SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Animations License

Flowing animations and are distributed under Creative Commons License 2.0:

Error screen by Chetan Potnuru

Building Screen by Carolina Cajazeira

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
192.168.85.1 - - [26/Jun/2022:06:07:07 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 24 192.168.85.1 - - [26/Jun/2022:06:07:11 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 24 192.168.85.1 - - [26/Jun/2022:06:07:11 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 24 192.168.85.1 - - [26/Jun/2022:06:07:11 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 200 12925 192.168.85.1 - - [26/Jun/2022:06:07:11 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 200 12925 192.168.85.1 - - [26/Jun/2022:06:07:11 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 200 12925 192.168.85.1 - - [26/Jun/2022:06:07:11 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 200 14 192.168.85.1 - - [26/Jun/2022:06:08:06 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 15 192.168.85.1 - - [26/Jun/2022:06:08:16 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 1227 192.168.85.1 - - [26/Jun/2022:06:10:15 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 79 192.168.85.1 - - [26/Jun/2022:06:13:25 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 404 752 192.168.85.1 - - [26/Jun/2022:06:16:42 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 35 192.168.85.1 - - [26/Jun/2022:06:16:57 -0400] "GET //struts2-showcase/hhh.jsp HTTP/1.1" 403 642 192.168.85.1 - - [26/Jun/2022:06:18:55 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 35 192.168.85.1 - - [26/Jun/2022:06:19:02 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 35 192.168.85.1 - - [26/Jun/2022:06:19:09 -0400] "GET //struts2-showcase/hhh1.jsp HTTP/1.1" 403 642 192.168.85.1 - - [26/Jun/2022:06:19:34 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 400 192.168.85.1 - - [26/Jun/2022:06:20:37 -0400] "POST /struts2-showcase/index.action HTTP/1.1" 500 5 192.168.85.1 - - [26/Jun/2022:06:20:42 -0400] "GET //struts2-showcase/hhh1.jsp HTTP/1.1" 403 642 192.168.85.1 - - [26/Jun/2022:06:20:46 -0400] "GET //struts2-showcase/hhh.jsp HTTP/1.1" 403 642 192.168.85.1 - - [26/Jun/2022:06:20:51 -0400] "GET /struts2-showcase/hhh.jsp HTTP/1.1" 403 642
07-12

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值