首页 > 解决方案 > rxjava 工作时 main 函数死了。请有任何解决方案

问题描述

我正在尝试使用 RXjava 获取 access_token。

我运行了程序并调用了请求 access_token 的函数,但该过程以代码 0 结束。

我认为连接服务器时主线程已死

我的解决方案是 Thread.sleep(sometime) 给很短的时间来得到回应。

我也试过

val runnable = Runnable{ getToken() }
val thread = Thread(runnable)
thread.run()
thread.join()

但它没有用..

这是我下面的代码

fun main(args : Array<String>) {
    getToken()

//    Thread.sleep(10000) // it works but don't want to do with this
}



fun getToken() {
    val id = "test"
    val pw = "test"
    println(id + " " + pw)

    val oAuthService = Retrofit.Builder()
        .baseUrl(URL)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .client(httpClient)
        .build()
        .create(OAuthService::class.java)

    oAuthService.getAccessToken(
        CLIENT_ID,
        CLIENT_SECRET,
        id,
        pw
    ).subscribeOn(Schedulers.io())
        .flatMap {
            when(it.error){
                null -> Single.just(TokenDto.Success(it.access_token?:"", it.expires_int?:0, it.token_type?:"", it.refresh_token?:""))
                else -> Single.just(TokenDto.Failure("failed"))
            }
        }
        .retry { times, throwable ->
            println(throwable)
            times < 3 }
        .subscribeBy(
            onSuccess = {
                println("onSuccess")
                when(it){
                    is TokenDto.Success -> {
                        println("accessToken : ${it.access_token}")
                    }
                    is TokenDto.Failure -> {
                        println("failed : ${it.msg}")
                    }
                }
            },
            onError = {
                println("onError")
            }
        )
}


改造

interface OAuthService {

    @FormUrlEncoded
    @POST("oauth2/token")
    fun getAccessToken(
        @Field("client_id") client_id:String,
        @Field("client_secret") client_secret:String,
        @Field("username") username:String,
        @Field("password") password:String
    ):Single<TokenResponse>

标签: kotlinrx-javaretrofit2rx-java2rx-kotlin

解决方案


Your subscription to getAccessToken is asynchronous. That's mean that subscribeBy returns immediately and then your main thread is terminated because it has nothing to do. You can use blockingSubscribeBy if you have Observable or blockingGet in a case when you use Single. Both of the operators should block the subscription.

I also want to clarify that blocking is bad, you should avoid it. Specifically, in your situation, it's ok because you want to block the execution in the main function which is kind of "end of the world" of your program.


推荐阅读