NetworkOnMainThread 与 Scheduler.io()

NetworkOnMainThread with Scheduler.io()

我试过使用 Scheduler.newThread() 和 Scheduler.io() 但还是不行 这是我的代码

Observable<Response> loginObservable = Observable.create(new ObservableOnSubscribe<Response>() {
            @Override
            public void subscribe(final ObservableEmitter<Response> emitter) throws Exception {

                btSignin.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if(validateFields()) {

                           // progressDialog.show();

                            Configs configs = new Configs(LoginActivity.this);
                            String versionName = new AppUtils(LoginActivity.this).getVersionName();

                            credentials.setGrantType(GRANT_TYPE_PASSWORD);
                            credentials.setUserName(username.getText().toString().trim());
                            credentials.setPassword(password.getText().toString());
                            credentials.setAppId(configs.getValue(APP_ID));
                            credentials.setOs(Build.VERSION_CODES.class.getFields()[Build.VERSION.SDK_INT].getName());
                            credentials.setBrowser(versionName);

                            // TODO: 05-Jul-17 get device type programmatically
                            credentials.setDevice("Tablet");

                            httpAuth = new HttpAuth.Builder()
                                    .setBaseUrl(configs.getValue(BASE_URL))
                                    .setCredentials(credentials)
                                    .build();
                           // ** This is network request**
                            Response response = httpAuth.loginToken("Token", TOKEN_NEW);

                            emitter.onNext(response);
                            emitter.onComplete();
                        }
                    }
                });
            }
        });

这就是我订阅的方式

loginObservable
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())

                .subscribe(observer);

android.os.NetworkOnMainThreadException Response response = httpAuth.loginToken("Token", TOKEN_NEW);

请帮忙。

您只将 onClickListener 设置为 Schedulers.newThread() 中的按钮,但 onClick 中执行的代码是 运行 在主线程上执行的。这就是异常的原因。

当您订阅 Observable 时,您只是为 Button 设置了一个 clickListener。你应该做的是创建这样的逻辑:

btSignin.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
        getLoginObservable()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer);
    }
}



Observable<Response> getLoginObservable() {
    return new ObservableOnSubscribe<Response>() {
        @Override
        public void subscribe(final ObservableEmitter<Response> emitter) throws Exception {
             // create your request
             Response response = httpAuth.loginToken("Token", TOKEN_NEW);

             emitter.onNext(response);
             emitter.onComplete();
        }
    }
}

我不太喜欢这种方法,因为感觉就像你在打破反应式范式。所以另一种选择是将您的流程直接绑定到点击事件。您可以手动完成,也可以依赖一个好的库(来自 Jake Wharton)RxBinding。使用此库,您可以创建一个 Observable 来发出与点击事件关联的项目。然后您可以将此 Observable 与您的 "stream" 连接起来,例如使用 flatMap 运算符。

RxView.clicks(btSignin) // this creates an Observable

另一个好的技巧是使用 Retrofit 进行网络请求。通过这种方式,您可以直接获取发出响应的Observable