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.
- 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 Kotlin- Mutexto safely handle concurrent refresh attempts
- TokenAuthenticator: Basic token refresh without synchronization (for comparison/demo)
 
This project includes two authenticator classes to demonstrate token refreshing:
- TokenAuthenticator– Basic implementation
- TokenAuthenticatorMutex– Uses- Mutexto 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:- emilys
- password:- emilyspass
- expiresInMins:- 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 

