通过runBlocking Kotlin阻止Application类

时间:2019-06-17 18:24:44

标签: android kotlin kotlin-coroutines

我对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抱怨。

1 个答案:

答案 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")


    }