如何在Kotlin中使用Retrofit和Observables创建异步调用?

时间:2017-11-14 22:10:57

标签: android kotlin retrofit2

我想使用Retrofit2库进行API调用,返回泛型类型observable。

我收到错误:android.os.NetworkOnMainThreadException,同时拨打电话。

2 个答案:

答案 0 :(得分:7)

看起来很容易解决,需要考虑两种情况。:1)如果你没有使用RXJava或2)如果你正在使用它

  

1)如果您不使用RXJava

拨打电话时,您应该使用enqueue方法。您得到的错误是因为您在同一个线程(MainThread)上调用响应

以下是使用Enotue with 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允许您非常容易地在并发线程中指导操作并在主线程上观察结果。这是一个很好的教程,解释了如何do that 用简单而众所周知的模式(参见符号)

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

与RXJava的新人不同的是:  默认RXJava上的 不会调用并发线程 ,由你来完成所有&#34;脏&#34;的subcribeOn。工作,然后用ObserveOn在主线程上观察结果。

对于主体来说很容易理解,将它们与两种着名的AsyncTask方法进行比较:doInBackgroundonPostExecute

编辑:如果您或将来的用户遇到问题,请同时查看此post

答案 1 :(得分:1)

使用Retrofit / RxJava,网络调用将默认在订阅从存根返回的Observable的线程上执行。在Android上,我们通常在&#34; main&#34;线程,并且不允许在此线程上访问网络,因此出错。

解决方案是告诉RxJava在不同的线程上订阅Observable:

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

Schedulers.io()是对调度程序的引用,该调度程序使用一组专门用于IO操作的线程。

.observeOn允许您安全地在主线程上处理结果。