Основная функция не работает, пока работает rxjava.любое решение, пожалуйста - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь получить access_token с RXjava.

Я запустил программу и вызвал функцию, которая запрашивает 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>

1 Ответ

1 голос
/ 22 мая 2019

Ваша подписка на getAccessToken является асинхронной.Это означает, что subscribeBy возвращается немедленно, и тогда ваш основной поток прерывается, потому что он не имеет ничего общего.Вы можете использовать blockingSubscribeBy, если у вас есть Observable или blockingGet в случае, если вы используете Single.Оба оператора должны заблокировать подписку.

Я также хочу уточнить, что блокировка плохая, ее следует избегать.В частности, в вашей ситуации это нормально, потому что вы хотите заблокировать выполнение в главной функции, которая является своего рода «концом света» вашей программы.

...