使用 Retrofit 和 RxJava 使用不同的参数多次发送特定请求
Send specific request multiple times with different parameters using Retrofit & RxJava
我有 n 个带有自己文本的 EditText:
editText1 -> 文本:13
editText2 -> 文本:15
editText3 -> 文本:20
...
并且有一个名为 getNewValue(String currentValue)
的 API 方法。它将根据当前值获取每个 EditText 的新值。
场景:
getNewValue()
如果每个 EditText 都获得焦点,将发送请求,并且新值将设置在聚焦的 EditText 上。
如何使用 Retrofit、RxJava 和 ViewModel 实现这个目标?
我试过这段代码:
片段:
editText1.setOnFocusChangeListener(getEtFocusChangeListener(editText1.getText().toString()));
editText2.setOnFocusChangeListener(getEtFocusChangeListener(editText2.getText().toString()));
editText3.setOnFocusChangeListener(getEtFocusChangeListener(editText3.getText().toString()));
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(currentValue);
viewModel.getNewValueResponse().observe(getViewLifecycleOwner(), newValue -> et.setText(newValue));
viewModel.getNewValueError().observe(getViewLifecycleOwner(), throwable -> Log.i(TAG, "New Value Error -----> " + throwable));
}
};
}
ViewModel:
private final MutableLiveData<String> newValueResponse = new MutableLiveData<>();
private final MutableLiveData<Throwable> newValueError = new MutableLiveData<>();
public void getNewValue(String currentValue) {
apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
newValueResponse.postValue(newValue);
}
@Override
public void onError(@NonNull Throwable throwable) {
newValueError.postValue(throwable);
}
});
}
public LiveData<String> getNewValueResponse() {
return newValueResponse;
}
public LiveData<Throwable> getNewValueError() {
return newValueError;
}
Api服务:
@GET("Values/GetNewValue")
Single<String> getNewValue(@Query("currentValue") String currentValue);
一个解决方案是声明一个全局变量来保存最后一个焦点 EditText
并在请求响应时使用它,但我认为有更好更智能的解决方案。
我对Android编程不是很熟悉,如果我遗漏了一些东西并犯了任何错误,我深表歉意,但是你为什么不传递对EditText
已经关注的引用getNewValue
方法?
考虑例如:
private final MutableLiveData<Pair<EditText, String>> newValueResponse = new MutableLiveData<>();
private final MutableLiveData<air<EditText, Throwable>> newValueError = new MutableLiveData<>();
//...
public void getNewValue(final EditText editText, final String currentValue) {
apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
newValueResponse.postValue(Pair.create(editText, newValue));
}
@Override
public void onError(@NonNull Throwable throwable) {
newValueError.postValue(Pair.create(editText, throwable));
}
});
}
public LiveData<Pair<EditText, String>> getNewValueResponse() {
return newValueResponse;
}
public LiveData<Pair<EditText, Throwable>> getNewValueError() {
return newValueError;
}
OnFocusChangeListener
将如下所示:
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue);
viewModel.getNewValueResponse().observe(getViewLifecycleOwner(), newValue -> newValue.first.setText(newValue.second));
viewModel.getNewValueError().observe(getViewLifecycleOwner(), throwable -> Log.i(TAG, "New Value Error -----> " + throwable.second));
}
};
}
在某种程度上,我发现最后一个代码片段很奇怪,因为如果你考虑一下,由于 API 调用的异步性质,实际结果可能是不同的 EditText
.也许我可以通过类似的方式缓解这个问题:
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue);
viewModel.getNewValueResponse().observe(getViewLifecycleOwner(), newValue -> {
// Only perform the operation if the `EditText` is the affected one
if (et.equals(newValue.first)) {
newValue.first.setText(newValue.second);
}
});
viewModel.getNewValueError().observe(getViewLifecycleOwner(), throwable -> {
if (et.equals(throwable.first)) {
Log.i(TAG, "New Value Error -----> " + throwable.second);
}
});
}
};
}
在我看来,根据用例,您可以去掉 newValueResponse
和 newValueError
MutableLiveData
实例。例如:
public void getNewValue(final EditText editText, final String currentValue) {
apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
editText.seText(newValue);
}
@Override
public void onError(@NonNull Throwable throwable) {
Log.i(TAG, "New Value Error -----> " + throwable);
}
});
}
并且:
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue);
}
};
}
或者更语义化:
public void getNewValue(final String currentValue) {
return apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io());
}
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue)
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
et.seText(newValue);
}
@Override
public void onError(@NonNull Throwable throwable) {
Log.i(TAG, "New Value Error -----> " + throwable);
}
});
}
};
}
我有 n 个带有自己文本的 EditText:
editText1 -> 文本:13
editText2 -> 文本:15
editText3 -> 文本:20
...
并且有一个名为 getNewValue(String currentValue)
的 API 方法。它将根据当前值获取每个 EditText 的新值。
场景:
getNewValue()
如果每个 EditText 都获得焦点,将发送请求,并且新值将设置在聚焦的 EditText 上。
如何使用 Retrofit、RxJava 和 ViewModel 实现这个目标?
我试过这段代码:
片段:
editText1.setOnFocusChangeListener(getEtFocusChangeListener(editText1.getText().toString()));
editText2.setOnFocusChangeListener(getEtFocusChangeListener(editText2.getText().toString()));
editText3.setOnFocusChangeListener(getEtFocusChangeListener(editText3.getText().toString()));
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(currentValue);
viewModel.getNewValueResponse().observe(getViewLifecycleOwner(), newValue -> et.setText(newValue));
viewModel.getNewValueError().observe(getViewLifecycleOwner(), throwable -> Log.i(TAG, "New Value Error -----> " + throwable));
}
};
}
ViewModel:
private final MutableLiveData<String> newValueResponse = new MutableLiveData<>();
private final MutableLiveData<Throwable> newValueError = new MutableLiveData<>();
public void getNewValue(String currentValue) {
apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
newValueResponse.postValue(newValue);
}
@Override
public void onError(@NonNull Throwable throwable) {
newValueError.postValue(throwable);
}
});
}
public LiveData<String> getNewValueResponse() {
return newValueResponse;
}
public LiveData<Throwable> getNewValueError() {
return newValueError;
}
Api服务:
@GET("Values/GetNewValue")
Single<String> getNewValue(@Query("currentValue") String currentValue);
一个解决方案是声明一个全局变量来保存最后一个焦点 EditText
并在请求响应时使用它,但我认为有更好更智能的解决方案。
我对Android编程不是很熟悉,如果我遗漏了一些东西并犯了任何错误,我深表歉意,但是你为什么不传递对EditText
已经关注的引用getNewValue
方法?
考虑例如:
private final MutableLiveData<Pair<EditText, String>> newValueResponse = new MutableLiveData<>();
private final MutableLiveData<air<EditText, Throwable>> newValueError = new MutableLiveData<>();
//...
public void getNewValue(final EditText editText, final String currentValue) {
apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
newValueResponse.postValue(Pair.create(editText, newValue));
}
@Override
public void onError(@NonNull Throwable throwable) {
newValueError.postValue(Pair.create(editText, throwable));
}
});
}
public LiveData<Pair<EditText, String>> getNewValueResponse() {
return newValueResponse;
}
public LiveData<Pair<EditText, Throwable>> getNewValueError() {
return newValueError;
}
OnFocusChangeListener
将如下所示:
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue);
viewModel.getNewValueResponse().observe(getViewLifecycleOwner(), newValue -> newValue.first.setText(newValue.second));
viewModel.getNewValueError().observe(getViewLifecycleOwner(), throwable -> Log.i(TAG, "New Value Error -----> " + throwable.second));
}
};
}
在某种程度上,我发现最后一个代码片段很奇怪,因为如果你考虑一下,由于 API 调用的异步性质,实际结果可能是不同的 EditText
.也许我可以通过类似的方式缓解这个问题:
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue);
viewModel.getNewValueResponse().observe(getViewLifecycleOwner(), newValue -> {
// Only perform the operation if the `EditText` is the affected one
if (et.equals(newValue.first)) {
newValue.first.setText(newValue.second);
}
});
viewModel.getNewValueError().observe(getViewLifecycleOwner(), throwable -> {
if (et.equals(throwable.first)) {
Log.i(TAG, "New Value Error -----> " + throwable.second);
}
});
}
};
}
在我看来,根据用例,您可以去掉 newValueResponse
和 newValueError
MutableLiveData
实例。例如:
public void getNewValue(final EditText editText, final String currentValue) {
apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
editText.seText(newValue);
}
@Override
public void onError(@NonNull Throwable throwable) {
Log.i(TAG, "New Value Error -----> " + throwable);
}
});
}
并且:
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue);
}
};
}
或者更语义化:
public void getNewValue(final String currentValue) {
return apiService.getNewValue(currentValue)
.subscribeOn(Schedulers.io());
}
private View.OnFocusChangeListener getEtFocusChangeListener(String currentValue) {
return (view, hasFocus) -> {
if (hasFocus) {
EditText et = (EditText) v;
viewModel.getNewValue(et, currentValue)
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onSuccess(@NonNull String newValue) {
et.seText(newValue);
}
@Override
public void onError(@NonNull Throwable throwable) {
Log.i(TAG, "New Value Error -----> " + throwable);
}
});
}
};
}