8

我在使用 RxJava、Retrofit 和多窗口模式时遇到问题......我在 Activity 中使用 Retrofit 调用我们自己的 api(实际代码比这复杂一点):

api.getEvent(...)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidScheduler.mainThread())
  .subscribe(event -> setupUI(event),
             throwable -> showSnackbar(throwable));

当应用程序处于“正常”模式(全屏)时,一切运行正常......我可以将应用程序放在 bg 中,将其放回前台并再次调用 api 调用方法(它位于 onResume 方法中 - 种类of) 并且 UI 绘制没有问题。相反,当我激活多窗口模式时,会调用 onResume,成功调用 api 方法但永远不会到达 subscribe() 方法。这种情况的堆栈跟踪是:

Retrofit: java.io.InterruptedIOException: thread interrupted
       at okio.Timeout.throwIfReached(Timeout.java:145)
       at okio.Okio$1.write(Okio.java:77)
       at okio.RealBufferedSink.flush(RealBufferedSink.java:221)
       at com.squareup.okhttp.internal.framed.Http2$Writer.flush(Http2.java:381)
       at com.squareup.okhttp.internal.framed.FramedConnection.newStream(FramedConnection.java:283)
       at com.squareup.okhttp.internal.framed.FramedConnection.newStream(FramedConnection.java:249)
       at com.squareup.okhttp.internal.http.Http2xStream.writeRequestHeaders(Http2xStream.java:135)
       at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:710)
       at com.facebook.stetho.okhttp.StethoInterceptor.intercept(StethoInterceptor.java:67)
       at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:695)
       at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:576)
       at com.squareup.okhttp.Call.getResponse(Call.java:287)
       at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:243)
       at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:205)                                                                     at com.squareup.okhttp.Call.execute(Call.java:80)
       at com.newrelic.agent.android.instrumentation.okhttp2.CallExtension.execute(CallExtension.java:43)
       at retrofit.client.OkClient.execute(OkClient.java:53)
       at com.newrelic.agent.android.instrumentation.retrofit.ClientExtension.execute(ClientExtension.java:42)
       at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
       at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
       at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265)
       at retrofit.RxSupport$2.run(RxSupport.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
       at retrofit.Platform$Android$2$1.run(Platform.java:142)
       at java.lang.Thread.run(Thread.java:761)

应用程序不会崩溃,但 UI 保持在“占位符”状态,并且加载 ProgressBar 会一直持续下去。

编辑:我在其他活动中具有相同的代码结构。这个问题并没有出现在其他地方。

4

1 回答 1

2

当应用程序进入多窗口模式时,会发生一些奇怪的生命周期回调序列。我已经登录onStartonResume和。查看结果:onPauseonStop

在此处输入图像描述

pause
stop
start
resume
pause

因此,最初打开的应用程序首先失去焦点,然后获得焦点,然后再次失去焦点(焦点转到下一个窗口)。

我相信您正在取消订阅onPause,因为您在 中发起了订阅onResume。这就是为什么subscribe()永远不会被调用的原因,因为它会立即被取消订阅。

于 2017-04-07T06:01:09.350 回答