Android NetworkOnMainThread与Scheduler.io()一起运行
我尝试过使用Scheduler.newThread()和Scheduler.io(),但仍然没有成功 这是我的密码Android NetworkOnMainThread与Scheduler.io()一起运行,android,reactive-programming,rx-android,rx-java2,Android,Reactive Programming,Rx Android,Rx Java2,我尝试过使用Scheduler.newThread()和Scheduler.io(),但仍然没有成功 这是我的密码 Observable<Response> loginObservable = Observable.create(new ObservableOnSubscribe<Response>() { @Override public void subscribe(final ObservableEmitter<
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();
}
}
});
}
});
获取android.os.NetworkOnMainThreadException,位于以下位置Response Response=httpAuth.loginToken(“令牌”,Token\u NEW)代码>
请提供帮助。您仅将onClick
设置为调度程序.newThread()中的按钮,但在onClick
中执行的代码在主线程上运行。这就是例外的原因 当您订阅您的可观察的
时,您只需将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();
}
}
}
另一个好的提示是对网络请求使用改装。通过这种方式,您可以直接获得发出响应的可观察的。谢谢,听起来不错。请建议一种我不想创建另一个线程的方法,因为这会扼杀使用调度程序的目的。@eCDroid,我将编辑我的答案,以显示我认为应该如何be@eCDroid,好的,我对RxJava不够熟悉,无法向您展示它应该是怎样的,但是您应该在onclick中进行订阅。所以你基本上是点击按钮,然后它订阅并进行网络操作。这不是对每次点击订阅观察者都是多余的吗?无论如何,谢谢你的回答和建议:)@eCDroid,不幸的是,我不知道如何正确地实现它。Rxjava不太好,其他人都想回答这个问题。创建一个新的可观察对象并在每次点击按钮时订阅它不是多余和昂贵的吗?这不是一个大问题。但正如我所说,这就是为什么我不那么喜欢它。使用RxBinding,您可以从单击事件创建一个可观察的事件,并使用map
或flatMap
将该事件转换为其他事件,以便执行其他操作,如网络呼叫。谢谢您的回答
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();
}
}
}
RxView.clicks(btSignin) // this creates an Observable