LiveDataReactiveStreams.fromPublisher 在没有互联网连接时崩溃应用程序


W/System.err: java.net.UnknownHostException: Unable to resolve host "api.rawg.io": No address associated with hostname
W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:156)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
at java.net.InetAddress.getAllByName(InetAddress.java:1152)
at okhttp3.Dns$1.lookup(Dns.java:40)
at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:214)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall.execute(RealCall.java:92)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:186)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
at io.reactivex.Observable.subscribe(Observable.java:10838)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:10838)
at io.reactivex.internal.operators.flowable.FlowableFromObservable.subscribeActual(FlowableFromObservable.java:29)
at io.reactivex.Flowable.subscribe(Flowable.java:12978)
at io.reactivex.internal.operators.flowable.FlowableOnBackpressureLatest.subscribeActual(FlowableOnBackpressureLatest.java:32)
at io.reactivex.Flowable.subscribe(Flowable.java:12978)
at io.reactivex.internal.operators.flowable.FlowableDoOnEach.subscribeActual(FlowableDoOnEach.java:50)
at io.reactivex.Flowable.subscribe(Flowable.java:12978)
at io.reactivex.Flowable.subscribe(Flowable.java:12924)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:929)
W/System.err: Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
W/System.err:     at libcore.io.Linux.android_getaddrinfo(Native Method)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:200)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135)
... 43 more

当应用程序与互联网连接良好时,但是当我没有互联网连接时,我的应用程序崩溃了。我想处理这个异常,但我尝试的任何事情都没有帮助:/。我也尝试检查源是否不为空.我正在使用Dagger 2,Retrofit 2,RxJava,viewModel。

class VideoViewModel : ViewModel {
private val authApi: AuthApi
private val games: MediatorLiveData<TopGames> = MediatorLiveData<TopGames>() 
@Inject
constructor(authApis: AuthApi) {
authApi = authApis
}

fun authenticateWithId(dates: String) {
val source: LiveData<TopGames> = LiveDataReactiveStreams.fromPublisher(
authApi.getTopGames(dates, "-added").doOnError { t-> print("${t.printStackTrace()}  doOnError") }
.subscribeOn(Schedulers.io())
)
games.addSource<TopGames>(source, object : androidx.lifecycle.Observer<TopGames?> {
override fun onChanged(t: TopGames?) {
//   Log.d("TAG", "VideoonChanged: $t")
games.value = t
games.removeSource(source)
}
})
}

fun observeGaneInfo(): LiveData<TopGames?>? {
return games
}
}

其他类

interface AuthApi {

@GET("/api/games")
fun getTopGames(
@Query("dates") dates: String,
@Query("ordering") ordering: String
): Flowable<TopGames>
}

您的 rx 链中没有错误处理。所以你可能想做这样的事情。

val source: LiveData<TopGames> = LiveDataReactiveStreams.fromPublisher(
authApi.getTopGames(dates, "-added")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
games.value = it
},
{
// error handling goes here
}
)
)

您可以为错误消息设置单独的LiveData,但更干净的方法是创建类State如其他回复中所述,因此您只有视图状态更新的单一源。

另请注意,subscribe方法返回Disposable最好ViewModel'sonCleared方法处理。

解决方案 :

在状态上创建数据类

data class DataWithStates<T>(
val data: T? = null,
val states: Throwable? = null
)

在我的实时数据中,我将 val 源:LiveData 更改为 LiveData并完美运行

fun authenticateWithId(dates: String) {
val source: LiveData<DataWithStates<TopGames>> = LiveDataReactiveStreams.fromPublisher(
authApi.getTopGames(dates, "-added").map { lstUser -> DataWithStates(lstUser) }.onErrorReturn { ex -> DataWithStates(states = ex) }
.subscribeOn(Schedulers.io())
)
games.addSource<DataWithStates<TopGames>>(source, object : androidx.lifecycle.Observer<DataWithStates<TopGames>> {
override fun onChanged(t: DataWithStates<TopGames>) {
//   Log.d("TAG", "VideoonChanged: $t")
games.value = t.data
games.removeSource(source)
}
})
}

有用的链接 RxJava 到实时数据错误处理