Как создать асинхронный вызов с помощью дооснащения и наблюдения в Котлине?

Я хочу совершать вызовы API с помощью библиотеки Retrofit2, возвращает общий тип наблюдаемого.

Я получаю сообщение об ошибке: android.os.NetworkOnMainThreadException при выполнении вызовов.

Выглядит очень легко решить, два случая для рассмотрения. : 1) Если вы не используете RXJava или 2) если вы используете его

1) Если вы НЕ используете RXJava

Вы должны использовать метод enqueue при выполнении вызова. Ошибка, которую вы получаете, связана с тем, что вы вызываете ответ на тот же поток (MainThread)

Вот пример, взятый из Интернета, который использует Enqueue с Kotlin, который, возможно, вы можете адаптировать к вашему делу

override fun loadPokemonList(pokemonListListener: PokemonListListener) { call = pokemonService.getPokedex(); call.enqueue(object : Callback<PokeDex> { override fun onResponse(call: Call<PokeDex>?, response: Response<PokeDex>?) { if (response != null && response.isSuccessful) { pokemonListListener.onSuccess(response.body()) } else { pokemonListListener.onFailure(appContext.getString(R.string.error_fetching_data)) } } override fun onFailure(call: Call<PokeDex>?, t: Throwable?) { pokemonListListener.onFailure(appContext.getString(R.string.error_fetching_data)) } }) } 

2) Если вы используете RXJava (обычно версию 2, имейте в виду , что вы найдете несколько руководств для первой версии в Интернете)

Но, пожалуйста, подумайте, что большинство разработчиков сегодня решают этот асинхронный вызов, используя RXJava2, что является вторым случаем, о котором я упоминал в начале сообщения. Вам потребуется несколько часов, чтобы понять основы этого, но как только вы это сделаете, у вас будет отличное умение приносить с собой и управлять такими вызовами (даже несколькими), будет очень просто. На самом деле RXJava позволяет вам очень легко направить операцию в параллельном потоке и наблюдать результат на главной теме. Вот хороший учебник, в котором объясняется, как сделать это с помощью простого и хорошо известного шаблона (см. Обозначения)

 Observable<List<TrendsResponse>> .subscribeOn(Schedulers.io())//Run the call on another Thread .observeOn(AndroidSchedulers.mainThread())//observe on the Main Thread .subscribe(); 

Иными словами, что люди, новые для RXJava, думают: по умолчанию RXJava не вызывает параллельный subcribeOn , вам subcribeOn что делать с subcribeOn которая выполняет всю «грязную» работу, а затем наблюдать результат в главной теме с ObserveOn .

Для принципалов легко понять, что сравнение их обоих с двумя известными методами AsyncTask: doInBackground и onPostExecute

EDIT: Пожалуйста, посмотрите также этот пост, если у вас или будущих пользователей есть проблемы.

С помощью Retrofit / RxJava сетевой вызов будет выполняться по умолчанию в потоке, который подписывается на Observable, возвращенный из заглушки. На Android мы обычно выполняем «основной» поток, и не разрешается доступ к сети в этом потоке, следовательно, ошибка.

Решение состоит в том, чтобы сообщить RxJava подписаться на Observable в другом потоке:

 getDataFromAPI(/*...*/) .subscribeOn(Schedulers.io()) .observerOn(AndroidSchedulers.mainThread()) .subscribe({ /* result available in `it` */ }) 

Schedulers.io() является ссылкой на планировщик, который использует набор потоков, специально предназначенных для использования в операциях ввода-вывода.

Функция .observeOn позволяет безопасно обрабатывать результат обратно в основной поток.

Intereting Posts