Основная функция мертва, пока работает 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>
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Я только что нашел простой способ! просто удалив «.subscribeOn(Schedulers.io())», пусть процесс использует основной поток.

aguagu 22.05.2019 11:37

Понимаю. Но у вас может быть ситуация, когда где-то в вашем потоке есть скрытый от вас переключатель планировщика. По этой причине лучше использовать блочную операцию

Vinipuh007 22.05.2019 12:37

согласна!! Большое спасибо

aguagu 23.05.2019 01:59

Другие вопросы по теме