All Projects → LordRaydenMK → SuperheroesAndroid

LordRaydenMK / SuperheroesAndroid

Licence: MIT License
Android sample app using the Marvel API to show a list of superheroes

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to SuperheroesAndroid

RiRi
An optical character recognition mobile application built using Kotlin Multiplatform Mobile and Azure Cognitive Services
Stars: ✭ 31 (+121.43%)
Mutual labels:  kotlin-coroutines
wobbuffetch
Reactive wrapper for Fetch API
Stars: ✭ 28 (+100%)
Mutual labels:  reactive-programming
RxJava-Codelab
Codelab project for demonstration of RxJava features
Stars: ✭ 44 (+214.29%)
Mutual labels:  reactive-programming
Retrofit2-Flow-Call-Adapter
A Retrofit 2 adapter for Kotlin Flows.
Stars: ✭ 41 (+192.86%)
Mutual labels:  kotlin-coroutines
react-mobx-router5
React components for routing solution using router5 and mobx
Stars: ✭ 58 (+314.29%)
Mutual labels:  reactive-programming
foodies
A clean MVVM architecture android application
Stars: ✭ 14 (+0%)
Mutual labels:  kotlin-coroutines
queueable
Convert streams to async ⌛ iterables ➰
Stars: ✭ 43 (+207.14%)
Mutual labels:  reactive-programming
mcuapi
🦸 Marvel Cinematic Universe API
Stars: ✭ 14 (+0%)
Mutual labels:  marvel-api
kotlin-coroutines-android
Kotlin Coroutines for Android
Stars: ✭ 14 (+0%)
Mutual labels:  kotlin-coroutines
rxify
Now: RxJava Playground, Previous: Demo for the talk at DroidconIN 2016, Droidcon Boston 2017 and Codelab for GDG January Meetup
Stars: ✭ 59 (+321.43%)
Mutual labels:  reactive-programming
CoMvvmHelper
android mvvm 基础框架,适合日常快速开发。有需要添加的内容或者发现问题可以提 issue。
Stars: ✭ 26 (+85.71%)
Mutual labels:  kotlin-coroutines
stack
An Android app for browsing Stack Overflow and other Stack Exchange sites.
Stars: ✭ 218 (+1457.14%)
Mutual labels:  kotlin-coroutines
FireApp
FirebaseApp is built for learning purposes, especially to see how Firebase Products work together.
Stars: ✭ 34 (+142.86%)
Mutual labels:  kotlin-coroutines
TheMovieDB
TheMovieDB is an android app based on TMDB api.
Stars: ✭ 16 (+14.29%)
Mutual labels:  kotlin-coroutines
jda-ktx
Collection of useful Kotlin extensions for JDA
Stars: ✭ 49 (+250%)
Mutual labels:  kotlin-coroutines
Newz
Android App that shows Top Stories from the NY Times
Stars: ✭ 31 (+121.43%)
Mutual labels:  kotlin-coroutines
scalajs-all-in-one-template
The All-in-One Scala.js static web project template
Stars: ✭ 47 (+235.71%)
Mutual labels:  reactive-programming
RickAndMorty-AndroidMVVMSample
An android sample project using Jetpack libraries and MVVM design pattern
Stars: ✭ 17 (+21.43%)
Mutual labels:  kotlin-coroutines
fluid-mongo
Kotlin coroutine support for MongoDB built on top of the official Reactive Streams Java Driver
Stars: ✭ 27 (+92.86%)
Mutual labels:  kotlin-coroutines
reactive-pipes
A thin library around Reactive Extensions to simplify writing evented applications in C#.
Stars: ✭ 12 (-14.29%)
Mutual labels:  reactive-programming

Superheroes App

A sample project using the Marvel API to show a list of superheroes and some stats about them.

Superheroes List Superhero Details Error & Retry
Superheroes List Superhero Details Error Loading

Marvel API KEY

The project need marvel_public_api_key and marvel_private_api_key to build. You can add them to your home level gradle.properties file (located in ~/.gradle on Unix based systems):

marvel_public_api_key=<PUBLIC API KEY HERE>
marvel_private_api_key=<PRIVATE API KEY HERE>

or using -Pmarvel_public_api_key=<PUBLIC API KEY HERE> -Pmarvel_private_api_key=<PRIVATE API KEY HERE> to each gradle command e.g.:

./gradlew assembleDebug -Pmarvel_public_api_key=<PUBLIC API KEY HERE> -Pmarvel_private_api_key=<PRIVATE API KEY HERE>

Check out the Marvel Developer portal for more info.

App Architecture

The app uses a reactive architecture built atop Flow. The app follows a layered architecture with data, domain and presentation layer. The package structure is an attempt to package by feature, however both screens share the data and domain layers. The app uses a single activity + fragments and the Jetpack Navigation Component.

Data Layer

The API call is modeled using Retrofit, KotlinX Serialization as the converter. The data layer converts the DTO objects to Domain objects. Any errors that happen up to this point are mapped to a sealed class SuperheroError (categorised as Recoverable on Unrecoverable). A custom exception SuperheroException that contains a property of the error is delivered as an RxJava error in the stream.

Domain Layer

The main class here is Superhero. It has a static create function that converts the string that comes from the API (as a thumbnail) into a HttpUrl also making sure it's https (so it works on Android).

Presentation Layer

The Fragment is not the view (MVVM view) here. There is a separate class that implements a Screen interface that handles all logic related to the view. It uses ViewBinding for findViewById. Data flows to this class trough the bind function that takes a view state (a class that describes the content of the screen). A screen exposes Flow<Action> for the user interactions (e.g. open details, retry...) to the Fragment.

Each fragment has a Jetpack ViewModel that:

  • exposes a single Flow<ViewState> backed by a MutableStateFlow (caching the last item) describing the state of the view at a given time
  • exposes a single Flow<Effect> backed by a Channel for side effects like navigation, Snackbar or similar. Event that happen when no-one is subscribed are cached. All events are delivered when subscribed
  • exposes a CoroutineScope with operations tied to it's lifecycle

The Fragment observes the Flow<ViewState> between onStart and onStop and updates the Sceen. The Fragment observes Flow<Effect> between onStart and onStop making sure fragment transactions are executed only when the view is active.

The Fragment observes the Flow<Action> from onStart until onStop. However any network calls that result from those interactions are de-coupled from this lifecycle. The operations triggered by the view actions are coupled to the ViewModel lifecycle and are only disposed in the ViewMode.onDispose() function. Check the fork() function for more details.

The logic is written as extension functions on top of a module (collection of dependencies).

Dependency Injection

The sample uses the DI approach from Simple Kotlin DI. The dependencies with Singleton scope live in the app as AppModule. Each fragment uses the AppModule dependencies and can add it's own (e.g. the ViewModel) that are un-scoped or use Jetpack for scoping (e.g. ViewModel).

The logic is written as extension functions on top of a module (collection of dependencies).

Testing

This sample uses kotest as a testing library. The presentation logic is tested by mocking the Retrofit Service and using a TestViewModel that uses MutableSharedFlow instead of MutableStateFlow and remembers all events. Tests use the real schedulers and Turbine for testing Flow.

The view is tested in isolation using Espresso, by setting a ViewState using bind() and verifying the correct elements are displayed/hidden and the text matches the expected. There is also one E2E espresso test that uses MockWebServer and tests both fragments + activity together. The E2E test is a bit flaky.

Acknowledgments

Approaches is this sample are heavily inspired by open source code I have read. It is impossible to list them all, but two samples that were key are:

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].