我对Dispatchers在Kotlin中的工作方式感到困惑
任务 在我的Application类中,我打算通过Room访问我的数据库,取出用户,取出他的JWT accessToken并将其设置在我的改造请求接收器使用的另一个对象中。
但是我希望所有这些代码都被阻塞,以便在Application类运行完毕时,已提取用户并将其设置在Inteceptor中。
问题 在从数据库中选择用户之前,我的应用程序类运行完毕。
会话类是访问Room的一种
这是我的课程的外观
class Session(private val userRepository: UserRepository, private var requestHeaders: RequestHeaders) {
var authenticationState: AuthenticationState = AuthenticationState.UNAUTHENTICATED
var loggedUser: User? by Delegates.observable<User?>(null) { _, _, user ->
if (user != null) {
user.run {
loggedRoles = roleCsv.split(",")
loggedRoles?.run {
if (this[0] == "Employer") {
employer = toEmployer()
} else if (this[0] == "Employee") {
employee = toEmployee()
}
}
authenticationState = AuthenticationState.AUTHENTICATED
requestHeaders.accessToken = accessToken
}
} else {
loggedRoles = null
employer = null
employee = null
authenticationState = AuthenticationState.UNAUTHENTICATED
requestHeaders.accessToken = null
}
}
var loggedRoles: List<String>? = null
var employee: Employee? = null
var employer: Employer? = null
init {
runBlocking(Dispatchers.IO) {
loggedUser = userRepository.loggedInUser()
Log.d("Session","User has been set")
}
}
// var currentCity
// var currentLanguage
}
enum class AuthenticationState {
AUTHENTICATED, // Initial state, the user needs to secretQuestion
UNAUTHENTICATED, // The user has authenticated successfully
LOGGED_OUT, // The user has logged out.
}
这是我的应用程序类
class MohreApplication : Application()
{
private val session:Session by inject()
private val mohreDatabase:MohreDatabase by inject() // this is integral. Never remove this from here. This seeds the data on database creation
override fun onCreate() {
super.onCreate()
startKoin {
androidLogger()
androidContext(this@MohreApplication)
modules(listOf(
platformModule,
networkModule,
....
))
}
Log.d("Session","Launching application")
}
创建会话的我的Koin模块
val platformModule = module {
// single { Navigator(androidApplication()) }
single { Session(get(),get()) }
single { CoroutineScope(Dispatchers.IO + Job()) }
}
在我的Logcat中,第一个“启动应用程序”打印出来,然后“已设置用户”
不是应该反向吗? 。这导致我的应用程序启动,而Session没有用户和MainActivity抱怨。
答案 0 :(得分:2)
by inject()
使用的是Kotlin延迟初始化。仅当查询session.loggedUser
时,init
块才会被触发。
对于您来说,当您在MainActivity中调用session.loggedUser
时,init
块将触发并阻塞调用线程。
您可以做的是
import org.koin.android.ext.android.get
class MohreApplication : Application()
{
private lateinit var session: Session
private lateinit var mohreDatabase: MohreDatabase // this is integral. Never remove this from here. This seeds the data on database creation
override fun onCreate() {
super.onCreate()
startKoin {
androidLogger()
androidContext(this@MohreApplication)
modules(listOf(
platformModule,
networkModule,
....
))
}
session = get()
mohreDatabase = get()
Log.d("Session","Launching application")
}