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

时间:2020-07-02 20:01:54

标签: android kotlin retrofit2 rx-java2

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

当应用程序与互联网的连接良好时,但是当我没有互联网连接时,我的应用程序崩溃。我想处理此异常,但是我尝试做的任何事情都没有帮助:/。我也尝试检查source是否不为null。我正在使用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>
}

2 个答案:

答案 0 :(得分:0)

解决方案:

在State上创建数据类

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)
            }
        })
    }

有用的链接 https://android.developreference.com/article/11762688/RxJava+to+live+data+error+Handling

答案 1 :(得分:0)

您的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类,如其他答复中所述,因此您只有单一的视图状态更新源

还请注意,从Disposable方法返回的subscribe最好放在ViewModel's onCleared方法中。