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

我想使用Retrofit2库进行API调用,返回genericstypesobservable。

我得到一个错误:android.os.NetworkOnMainThreadException,同时进行调用。

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

1)如果你不使用RXJava

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

这是一个从网络上使用Enqueue和Kotlin的例子,可能你可以适应你的情况

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

2)如果您使用的是RXJava (通常是版本2,请注意您会在网上find第一个版本的几个教程)

但请注意,今天大多数开发人员使用RXJava2来解决这个异步调用,这是我在发布之初提到的第二种情况。 要花几个小时才能理解的基础知识 ,但是一旦你做了,你将拥有一个很棒的技能,可以随身携带,管理这种types的电话(甚至是多个电话)将非常简单。 事实上,RXJava可以让你很容易地在一个并发的线程中指导操作,并观察主线程的结果。 这里有一个很好的教程,解释了如何使用简单和众所周知的模式(请参阅符号)

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

不同的是,新的RXJava认为: 在默认情况下,RXJava并不调用并发线程 ,由您来完成所有“脏”工作的subcribeOn ,然后使用ObserveOn观察主线程的结果。

对于原理很容易掌握,比较他们两个着名的方法AsyncTask: doInBackgroundonPostExecute

编辑:请看看这个post,如果你或未来的用户有问题。

使用Retrofit / RxJava,网络调用将默认在订阅从存根返回的Observable的线程上执行。 在Android上,我们通常在“主”线程上执行,并且不允许在该线程上访问网络,因此是错误的。

解决办法是告诉RxJava在另一个线程上订阅Observable:

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

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

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