Change-Id: Icf249596a5789c1305673cd962744a04d31108c5pull/1812/head
@ -0,0 +1,57 @@
|
|||||||
|
# Now in Android Project
|
||||||
|
|
||||||
|
Now in Android is a native Android mobile application written in Kotlin. It provides regular news
|
||||||
|
about Android development. Users can choose to follow topics, be notified when new content is
|
||||||
|
available, and bookmark items.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
This project is a modern Android application that follows the official architecture guidance from Google. It is a reactive, single-activity app that uses the following:
|
||||||
|
|
||||||
|
- **UI:** Built entirely with Jetpack Compose, including Material 3 components and adaptive layouts for different screen sizes.
|
||||||
|
- **State Management:** Unidirectional Data Flow (UDF) is implemented using Kotlin Coroutines and Flows. ViewModels act as state holders, exposing UI state as streams of data.
|
||||||
|
- **Dependency Injection:** Hilt is used for dependency injection throughout the app, simplifying the management of dependencies and improving testability.
|
||||||
|
- **Navigation:** Navigation is handled by Jetpack Navigation 2 for Compose, allowing for a declarative and type-safe way to navigate between screens.
|
||||||
|
- **Data:** The data layer is implemented using the repository pattern.
|
||||||
|
- **Local Data:** Room and DataStore are used for local data persistence.
|
||||||
|
- **Remote Data:** Retrofit and OkHttp are used for fetching data from the network.
|
||||||
|
- **Background Processing:** WorkManager is used for deferrable background tasks.
|
||||||
|
|
||||||
|
## Modules
|
||||||
|
The main Android app lives in the `app/` folder. Feature modules live in "feature/" and core and shared modules in "core/".
|
||||||
|
|
||||||
|
## Commands to Build & Test
|
||||||
|
|
||||||
|
The app and Android libraries have two product flavors: `demo` and `prod`.
|
||||||
|
|
||||||
|
- Build: `./gradlew assemble{Variant}`. Typically `assembleDemoDebug`.
|
||||||
|
- Fix linting/formatting: `./gradlew --init-script gradle/init.gradle.kts spotlessApply`
|
||||||
|
- Run local tests: `./gradlew {variant}Test`
|
||||||
|
- Run single test: `./gradlew {variant}Test --tests "com.example.myapp.MyTestClass"`
|
||||||
|
- Run local screenshot tests: `./gradlew verifyRoborazziDemoDebug`
|
||||||
|
|
||||||
|
### Instrumented tests
|
||||||
|
|
||||||
|
- Gradle-managed devices to run on device tests: `./gradlew pixel6api31aospDebugAndroidTest`. Also `pixel4api30aospatdDebugAndroidTest` and `pixelcapi30aospatdDebugAndroidTest`.
|
||||||
|
|
||||||
|
### Creating tests
|
||||||
|
|
||||||
|
#### Instrumented tests
|
||||||
|
|
||||||
|
- Tests for UI features should only use ComposeTestRule with a ComponentActivity.
|
||||||
|
- Bigger tests live in :app and they can start activities like MainActivity.
|
||||||
|
|
||||||
|
#### Local tests
|
||||||
|
|
||||||
|
- Kotlinx Coroutines for most assertions
|
||||||
|
- Turbine for complex coroutine tests
|
||||||
|
- Truth for assertions
|
||||||
|
|
||||||
|
## Continuous integration
|
||||||
|
|
||||||
|
- The workflows are defined in `.github/workflows/*.yaml` and they contain various checks.
|
||||||
|
- Screenshot tests are generated by CI, so they shouldn't be checked into the repo from a workstation.
|
||||||
|
|
||||||
|
## Version control and code location
|
||||||
|
|
||||||
|
- The project uses git and is hosted in github.com/android/nowinandroid.
|
@ -0,0 +1 @@
|
|||||||
|
* @dturner
|
@ -0,0 +1,2 @@
|
|||||||
|
# Repackage classes into the default package to reduce the size of descriptors.
|
||||||
|
-repackageclasses
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 703 B After Width: | Height: | Size: 873 B |
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 291 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 195 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 231 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
@ -1,4 +0,0 @@
|
|||||||
## This file provides default values to modules using the secrets-gradle-plugin. It is necessary
|
|
||||||
# because the secrets properties file is not under source control so CI builds will fail without
|
|
||||||
# default values.
|
|
||||||
BACKEND_URL="http://example.com"
|
|