This is a sample Android application demonstrating token refreshing using Retrofit Authenticator and Kotlin Mutex. It integrates with the DummyJSON API to simulate login and protected requests.
Android Token Refresh App Android Token Refresh App
- Kotlin
- Retrofit
- Coroutine Mutex
- Jetpack ViewModel
- MVVM Architecture
- DummyJSON API
- Login with DummyJSON API
- Stores and uses access & refresh tokens
- Automatically refreshes expired tokens using Retrofit Authenticator
- Two authenticator implementations:
TokenAuthenticatorMutex: Uses KotlinMutexto safely handle concurrent refresh attemptsTokenAuthenticator: Basic token refresh without synchronization (for comparison/demo)
This project includes two authenticator classes to demonstrate token refreshing:
TokenAuthenticator– Basic implementationTokenAuthenticatorMutex– UsesMutexto prevent multiple refresh calls
You can switch between them in the NetworkModule inside the di package:
object NetworkModule { @Provides @Singleton fun provideOkhttpClient( headerInterceptor: HeaderInterceptor, tokenAuthenticator: TokenAuthenticatorMutex // ← Change this to TokenAuthenticator to test without Mutex ): OkHttpClient { return RetrofitHelper.getOkHttpClient() .addInterceptor(headerInterceptor) .authenticator(tokenAuthenticator) .build() } }
- Retrofit Interceptor: Adds Authorization header
- Authenticator: Automatically refreshes token on 401 errors
- Mutex: Prevents multiple token refreshes at the same time
- When the app launches, it shows a Login screen.
- Press the Login button to authenticate using default credentials:
username:emilyspassword:emilyspassexpiresInMins:1→ Token expires in 1 minute
- After login, you are redirected to the Profile screen.
- On the Profile screen, press the Load button to trigger 3 parallel API calls.
- If the token is expired, all 3 calls will receive 401, and:
- Using
TokenAuthenticator: May trigger 3 refresh calls (undesirable). - Using
TokenAuthenticatorMutex: Only 1 refresh call happens, others wait for it (thread-safe).
- Using