основная функция мертва, пока работает rxjava. любое решение, пожалуйста

Я пытаюсь получить 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>

person aguagu    schedule 22.05.2019    source источник


Ответы (1)


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

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

person Vinipuh007    schedule 22.05.2019
comment
Я только что нашел простой способ! просто удалив .subscribeOn(Schedulers.io()), пусть процесс использует основной поток. - person aguagu; 22.05.2019
comment
Я понимаю. Но у вас может быть ситуация, когда где-то в вашем потоке есть скрытый от вас переключатель планировщика. По этой причине лучше использовать блочную операцию - person Vinipuh007; 22.05.2019
comment
соглашаться!! Большое спасибо - person aguagu; 23.05.2019