A small Kotlin Android sample showing a phone-number / password login + register flow against a remote JSON API, organised as a thin AndroidViewModel + Repository split. The repository layer uses Volley for HTTP and the auth token is persisted in SharedPreferences. Branded "MVVM Login" (applicationId = com.shayan.mvvm_login).
Heads-up: the previous README claimed Room, LiveData, Hilt, Flow, Material Design, JUnit/Espresso tests, and an MIT license. Most of that is not in the code — see Honest limitations.
- Working tree clean on
master(last commit46c442d, recent history is dominated by GitPulse marker commits). - Remote:
https://github.com/shayann07/MVVM-implementation.git. - This README was rewritten from a code audit. The previous README's feature list did not match the actual code.
-
view/MainActivitySplash— launcher activity. Inflates a Lottieanimation_splash, waits ~5.65 s, then readsPrefsDatabase.user_tokenfrom SharedPreferences and routes to eitherMainActivityLogin(no token) orMainActivityHome(token present). -
view/MainActivityLogin— phone + password form. CallsAuthViewModel.loginUser(...). On success it writes the returned token toPrefsDatabase.user_tokenand startsMainActivityHome. Has a button that opensMainActivityRegister. -
view/MainActivityRegister— first/last name, phone, password, confirm-password. Builds aModelUserand callsAuthViewModel.registerUser(...). -
view/MainActivityHome— a static iCloud-Reminders-style dashboard with cards (Today / Scheduled / All / Flagged / Completed) and two collapsible sections ("iCloud", "Outlook"). The toolbar overflow opens aPopupMenuwhose only item ("Log Out") clears prefs and pops back to login. -
viewmodel/AuthViewModel—AndroidViewModelthat holds a singleAuthRepositoryand re-issues the same callback-based API insideviewModelScope.launch { … }. There is noLiveData,StateFlow,Flow, orResultwrapper; success/error callbacks are forwarded straight through. -
repository/AuthRepository— buildsJSONObjectrequest bodies and POSTs to:https://cricdex.enfotrix.com/api/loginhttps://cricdex.enfotrix.com/api/register
via Volley
JsonObjectRequest, parsingsuccess,message, anddata.tokenfrom the JSON response. A newVolley.newRequestQueue(...)is allocated per call. -
model/ModelUser— data class withfirstName,lastName,phone,password,cPass,token.
- Language / build: Kotlin, AGP via
libs.versions.toml, JVM 11. - App config:
applicationId = com.shayan.mvvm_login,compileSdk = 35,minSdk = 24,targetSdk = 34,versionCode = 1,versionName = "1.0".viewBinding.enable = true. - Dependencies:
androidx.core.ktx,appcompat,material,volley,lottie,kotlinx-coroutines-android,androidx.activity,androidx.constraintlayout,androidx.lifecycle.viewmodel.ktx,androidx.fragment.ktx. JUnit + AndroidX-JUnit + Espresso for the default test scaffolds. - Permissions:
INTERNETonly.
The repo does not use Hilt/Dagger, Room, Retrofit/OkHttp, Gson/Moshi, LiveData, Flow, Jetpack Compose, Navigation Component, DataStore, or WorkManager.
MVVM-implementation/
├── app/
│ ├── build.gradle.kts # compileSdk 35, namespace com.shayan.mvvm_login
│ └── src/main/
│ ├── AndroidManifest.xml # 4 activities, INTERNET only
│ ├── java/com/shayan/mvvm_login/
│ │ ├── model/ModelUser.kt
│ │ ├── repository/AuthRepository.kt # Volley → cricdex.enfotrix.com
│ │ ├── viewmodel/AuthViewModel.kt # AndroidViewModel
│ │ └── view/
│ │ ├── MainActivitySplash.kt # 5.65 s token gate
│ │ ├── MainActivityLogin.kt
│ │ ├── MainActivityRegister.kt
│ │ └── MainActivityHome.kt # PopupMenu logout
│ └── res/ layout/, drawable/, menu/, raw/animation_splash, values/
├── build.gradle.kts
└── gradle/libs.versions.toml
- Clone, then provide a normal
local.properties(gitignored). - Open in Android Studio and let Gradle sync.
./gradlew :app:assembleDebug(or run from the IDE).
The login / register flow makes live calls to https://cricdex.enfotrix.com/api/{login,register} — without a valid account on that backend the flow cannot complete.
- No Room, no LiveData, no Flow, no Hilt, no Retrofit. The previous README listed all of these. The actual stack is Volley + plain callbacks + SharedPreferences, with an
AndroidViewModelthat adds a coroutine wrapper around synchronous Volley dispatches. viewModelScope.launchis cosmetic. Volley already runs work off the main thread and delivers callbacks on it; the wrapping coroutine inAuthViewModeldoes no suspending work.- Per-request Volley queue.
AuthRepositorycallsVolley.newRequestQueue(context.applicationContext)on every login / register. Should be a single shared queue. - Hardcoded API base URL.
loginUrl/registerUrlare constants inAuthRepository. NoBuildConfigfield, no debug / release split, no flavour swap. - Plaintext token storage.
user_tokenis written to plain SharedPreferences. UseEncryptedSharedPreferencesor DataStore +MasterKeyfor anything real. - All four activities are
android:exported="true". OnlyMainActivitySplashneeds to be exported. - Splash delay is ~5.65 s. Long for a launcher; consider
androidx.core:core-splashscreenand a shorter timeout. MainActivityHomeis a static mockup. No real reminder data — the cards and collapsible sections are pure UI.- No
LICENSEfile at the repo root, despite the previous README claiming MIT. - No tests beyond defaults. Only the generated
ExampleUnitTest/ExampleInstrumentedTestare present. - GitPulse marker comments. The previous
README.mdended with<!-- commit N -->and<!-- gitpulse:contribution … -->lines from a contribution-marker tool; those are not present in this rewrite.