Мне нужно добиться следующей логики c. Когда приложение запускается, загрузите userId из общих настроек, затем загрузите пользовательский объект из базы данных Room, чтобы, наконец, иметь возможность делать запросы на модификацию с использованием токена доступа от пользовательского объекта.
Вот то, чем я сейчас являюсь.
Инициализация репозитория пользователя с помощью Dagger при запуске приложения
class App : Application() {
companion object {
lateinit var userRepository: UserRepository
}
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.factory().create(applicationContext)
userRepository = appComponent.userRepository()
}
}
Загрузка userId
из sharedPrefs, а затем загрузка пользователя из БД при инициализации репозитория
@Singleton
class UserRepository @Inject constructor(
private val dao: UserDao,
private val sharedPrefs: SharedPreferences
) {
var user: User
private var userId: Int
init {
userId = sharedPrefs.getInt(PREFS_KEY_UID, 0)
GlobalScope.launch(Dispatchers.IO) {
user = dao.geUser(userId)
}
}
}
Перехват запросов на модификацию вставить токен в заголовок
interface Webservice {
companion object Factory {
private val headerInterceptor = Interceptor() {
val newRequest = it.request().newBuilder()
.addHeader("Authorization", "Bearer ${App.userRepository.user.token}")
.build()
it.proceed(newRequest)
}
fun create(): Webservice {
val client = OkHttpClient.Builder()
.addInterceptor(headerInterceptor)
.build();
val retrofit = retrofit2.Retrofit.Builder()
.client(client)
.baseUrl(BASE_URL)
.build()
return retrofit.create(Webservice::class.java)
}
}
}
Первый веб-запрос выполняется при создании ViewModel в MainActivity
class MainViewModel @Inject constructor(
private val repository: DataRepository
): ViewModel() {
val ticket: LiveData<Data> = repository.getData(viewModelScope)
}
@Singleton
class DataRepository @Inject constructor(
private val webservice: Webservice,
private val dao: DataDao
) {
fun getData(scope: CoroutineScope): LiveData<Data> {
refreshData(scope)
return dao.getData()
}
suspend fun refreshData(scope: CoroutineScope) {
scope.launch(Dispatchers.IO) {
...
val response = webservice.getData().awaitResponse()
...
dao.insert(response.body()!!)
...
}
}
}
Возможно, вы заметили, что я использую сопрограммы.
Как мне убедиться, что user
загружено из базы данных до отправки веб-запроса?