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
。
我试过使用 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
。