This is a sample app based on the walk through by Fahri Can. As I worked on the project, the App now has most of the code rewritten on my own.
First created in Nov 2021, looking at what I have done now, I found the quality of this App unacceptable, so I have updated again in Jul 2022.
The Android Development world is currently experiencing a shift of technology stack. Besides migrating from Java to Kotlin, we have a choice of Coroutines over RxJava, Hilt over Dagger, and JetPack Compose over the traditional XML View layouts. LiveData got replaced by Kotlin Flow quickly this year.
This Sample App is for demonstrating the traditional approach which applies XML
UI, Kotlin Coroutines, Kotlin Flow,
Dagger Hilt, PreferencesDataStore.
Previously this App used RxJava, but it is now rewritten using Coroutines because it is much
more simpler.
- Kotlin
- MVVM architecture
Jetpack Databinding- Kotlin Flow
- Material 3 with light and dark mode theming
- Gradle Kotlin DSL and Version Catalog
Jetpack ConstraintLayoutJetpack NavigationJetpack LifecycleJetpack PreferencesDataStoreKotlin CoroutinesKotlin FlowJetpack Room- DatabaseRetrofit2Moshi- Splash Screen API
Glide- Network imagesDagger Hilt- DITimber- LoggingLeakCanary- Memory leak detectionJUnit 4- Testskotest- Tests- Kover - code coverage
- codecov - code coverage
- Github Action - CI (current)
- Bitrise - CI (previously)
- Travis-CI - CI (previously)
- Ktlint Gradle - ktlint plugin to check and apply code autoformat
The original sample codes were over simplified. Modifications have been made to make the App look more production-ready.
- The UI architecture and list item layout have been redesigned to apply Material 3 specifications
- The database schema and DAOs have been improved to support more functionalities
- The RecyclerView has been modified to use ListAdapter, DiffUtils to avoid expensive notifyDataSetChanged()
- Additional handling done to preserve the scrolling state and avoid flickering during refresh
- Menu button has been added to allow manual refresh
- A dedicated Domain Model was added to separate the Network Data Model
- Introduced copy image link, and open Giphy page on browser functions
- Added user customisable API limit
- Added test cases - currently there are 27 unit tests and 7 instrumented tests
Planned enhancements are now logged as issues.
- Android Studio Iguana | 2023.2.1
- Android device or simulator running Android 9+ (API 28)
If you want to try out the app without building it, check out the Releases section where you can find the APK and App Bundles for each major version. A working Giphy API key was applied when building the app, therefore you can test it by just installing it.
- To build the app by yourself, you need your own Giphy API Key
Release builds will be signed if either the keystore file or environment variables are set. Otherwise, the app will be built unsigned and without the Giphy API key installed, which will not pull any data from the endpoint.
-
Android Keystore is not being stored in this repository. You need your own Keystore to generate the apk / App Bundle
-
If your project folder is at
/app/giphy-trending/, the Keystore file andkeystore.propertiesshould be placed at/app/ -
The format of
keystore.propertiesis:store=/app/release-key.keystore alias=<alias> pass=<alias password> storePass=<keystore password> giphyApiKey="<your API Key here>"
-
This project has been configured to build automatically on CI.
-
The following environment variables have been set to provide the keystore:
BITRISE = true HOME = <the home directory of the bitrise environment> BITRISEIO_ANDROID_KEYSTORE_PASSWORD = <your keystore password> BITRISEIO_ANDROID_KEYSTORE_ALIAS = <your keystore alias> BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD = <your keystore private key password> GIPHYAPIKEY= <your API Key>
./gradlew installDebug
// or
// ./gradlew installRelease
- Options are:
Debug,Release - Debug builds will have an App package name suffix
.debug
After August 2021, all new apps and games will be required to publish with the Android App Bundle format.
./gradlew clean bundleRelease
./gradlew clean assembleRelease
- The generated apk(s) will be stored under
app/build/outputs/apk/