【问题标题】:HTTP FAILED: java.io.IOException: Canceled in multiwindow modeHTTP FAILED:java.io.IOException:在多窗口模式下取消
【发布时间】:2017-04-03 05:56:18
【问题描述】:

当我的应用程序进入onPause 状态然后进入onResume 并且当我调用任何 API 时,我遇到了以下错误,我遇到了以下错误。

HTTP 失败:java.io.IOException:已取消

我正在使用 RxJava 和 Retrofit 来完成我所有的网络操作。以下是我的设置。

ApplicationComponent.java

@ApplicationScope
@Component(modules = {ContextModule.class, NetworkModule.class})
public interface ApplicationComponent {
    void inject(MyApplication myApplication);
}

ApplicationScope.java

@Scope
@Retention(RetentionPolicy.CLASS)
  public @interface ApplicationScope {
}

ContextModule.java

@Module
public class ContextModule {

    private Context context;

    public ContextModule(Context context){
        this.context = context;
    }

    @Provides
    @ApplicationScope
    public Context applicationContext(){
        return context.getApplicationContext();
    }

}

NetworkModule.java

@Module @ApplicationScope
public class NetworkModule {

    private final String BASE_CONTACT_URL = "";

    @Provides @ApplicationScope
    public PoolAPIService getPoolApiService(Retrofit retrofit){
        APIServiceapiServicece = retrofit.create(APIService.class);
        return apiServicece;
    }

    @Provides @ApplicationScope
    public Retrofit getRetrofit(OkHttpClient okHttpClient){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_CONTACT_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(okHttpClient)

                .build();

        return retrofit;
    }

    @Provides @ApplicationScope
    public OkHttpClient getOkHttpClient(HttpLoggingInterceptor interceptor, Cache cache){
        OkHttpClient okhttpclient = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .cache(cache)
                .build();
        return okhttpclient;
    }

    @Provides @ApplicationScope
    public HttpLoggingInterceptor getInterceptor(){
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.d("Log", message);
            }
        });
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return interceptor;
    }

    @Provides @ApplicationScope
    public Cache getCache(File cacheFile){
        Cache cache = new Cache(cacheFile, 10*1024*1024); //10MB size
        return cache;
    }

    @Provides @ApplicationScope
    public File getCacheFile(Context context){
        File cacheFile = new File(context.getCacheDir(), "cache");
        cacheFile.mkdirs();
        return cacheFile;
    }

    @Provides @ApplicationScope
    public Picasso getPicasso(Context context, OkHttpClient okHttpClient){
        Picasso picasso = new Picasso.Builder(context)
                .downloader(new OkHttp3Downloader(okHttpClient))
                .build();
        return picasso;
    }

}

我将它注入到我的应用程序类中。

MyApplication.java

public class MyApplication extends Application {

    ApplicationComponent applicationComponent;
    @Inject
    APIService apiService;

    @Override
    public void onCreate() {
        super.onCreate();

        applicationComponent = DaggerApplicationComponent.builder()
                .contextModule(new ContextModule(this))
                .build();

        applicationComponent.inject(this);
    }

    public APIService getAPIService(){
        return apiService;
    }

}

这就是我调用 API 服务的方式。

LoginActivity.java

//creating LoginService instance
LoginService loginService = new LoginService(((MyApplication)getApplication()).getAPIService());

.......

void login() {
        final String mobileNumber = view.getMobileNumber();
        final String password = view.getPassword();

        Subscriber<LoginResponse> subscriber = new Subscriber<LoginResponse>() {
            @Override
            public void onCompleted() {
                Log.d(TAG, "onCompleted");
                if(subscriptionLogin != null && !subscriptionLogin.isUnsubscribed()){
                    subscriptionLogin.unsubscribe();
                }
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "error: " + e.getMessage());
            }

            @Override
            public void onNext(LoginResponse loginResponse) {
                Log.d(TAG, loginResponse.message);
            }
        };


        LoginRequest request = new LoginRequest();
        request.mobileNumber = mobileNumber;
        request.password = password;

        subscriptionLogin = service.login(subscriber, request);

        compositeSubscription.add(subscriptionLogin);

 ....

  void onDestroy() {
    //unsubscribe all the subscription
    compositeSubscription.unsubscribe();
}

Logcat

--> POST http://.../.. http/1.1
Content-Type: application/json; charset=UTF-8
Content-Length: 32
--> END POST (32-byte body)
<-- HTTP FAILED: java.io.IOException: Canceled

【问题讨论】:

  • 你用compositeSubscription做什么?
  • 请发布完整的错误堆栈跟踪
  • 你在 onPause() 和 onResume() 做什么?
  • @yosriz 与改造或 rxjava 无关

标签: android rx-java retrofit2 dagger-2


【解决方案1】:

我已登录 onStartonResumeonPauseonStop。这是 Activity 进入多窗口模式时的输出:

我敢打赌,你没想到会在onResume 之后立即调用onPause。而且,只要您在onResume 中创建订阅,您就可以在onPause 中取消订阅,这会立即发生。

HTTP 失败:java.io.IOException:已取消

这意味着您已取消订阅(即您的改装电话已取消)。

【讨论】:

  • onStop 中也有compositeSubscription.unsubscribe()。感谢您让我朝着正确的方向前进。
  • @ik024,欢迎您。出乎意料的行为,至少对我而言。
猜你喜欢
  • 2014-06-17
  • 1970-01-01
  • 2017-05-02
  • 2017-02-22
  • 2012-12-10
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 2011-05-01
相关资源
最近更新 更多