gpt4 book ai didi

java - 观察通过改造更改的实时数据不会在更改时触发

转载 作者:行者123 更新时间:2023-12-01 23:51:07 25 4
gpt4 key购买 nike

首先,我检查了这两个问题 thisthis ,他们都没有解决我的问题。

其次,我将详细解释所有内容,所以请原谅我的长篇文章。

所以我第一次尝试在 android 中实现 MVVM,并遵循 tuto1 中的一些指南和步骤。和 tuto2 ,正如我的问题中所明确的,观察者中的 onchanged 方法没有触发,我不明白为什么。这是我的代码架构:

身份验证.java:

@FormUrlEncoded
@POST("service/api/login/")
Call<LoginResponse> login(@Field("username") String username,
@Field("password") String password);

为了处理错误,我按照 tuto1 实现了一个通用请求处理程序:

GenericRequestHandler.java:

public abstract class GenericRequestHandler<T extends Response> {

private static final String TAG = GenericRequestHandler.class.getName();

abstract protected Call<T> makeRequest();

public final MutableLiveData<DataWrapper<T>> doRequest() {
final MutableLiveData<DataWrapper<T>> liveData = new MutableLiveData<>();
final DataWrapper<T> dataWrapper = new DataWrapper<>();
makeRequest().enqueue(new ApiCallback<T>() {
@Override
protected void handleResponseData(T data) {
Log.e(TAG, "handleResponseData: being handled");
dataWrapper.setData(data);
liveData.postValue(dataWrapper);
}

@Override
protected void handleError(String message) {
Log.e(TAG, "handleError: error handled");
dataWrapper.setErrorMessage(message);
liveData.postValue(dataWrapper);
}

@Override
protected void handleException(Exception t) {
Log.e(TAG, "handleException: exception handled");
dataWrapper.setApiException(t);
liveData.postValue(dataWrapper);
}

@Override
protected void handleHttpCodes(int code) {
Log.e(TAG, "handleHttpCodes: code handled");
dataWrapper.setCode(code);
liveData.postValue(dataWrapper);
}
});
return liveData;
}

}

然后我从中制定了一个规范,以处理登录:

SignInRequestHandler.java:

public class SignInRequestHandler extends GenericRequestHandler {

private Authentication service = RestClient.getInstance().create(Authentication.class);
private String username, password;

public SignInRequestHandler(String username, String password) {
this.username = username;
this.password = password;
}

@Override
protected Call<LoginResponse> makeRequest() {
return service.login(username, password);
}

public MutableLiveData<DataWrapper<LoginResponse>> onAuthRequest() {
return doRequest();
}
}

出于验证目的,我在模型中调用登录请求处理程序,如下所示:

public MutableLiveData<DataWrapper<LoginResponse>> login() {
SignInRequestHandler handler = new SignInRequestHandler(this.userName, this.pass);
return handler.onAuthRequest();
}

这是 View 模型:

LoginVModel.java:

public class LoginVModel extends ViewModel {

private static final String TAG = LoginVModel.class.getName();

private Driver driver; //this is my model
public MutableLiveData<String> username;
public MutableLiveData<String> password;
public MutableLiveData<DataWrapper<LoginResponse>> loginLiveData;

public LoginVModel() {
driver = new Driver();
username = new MutableLiveData<>();
loginLiveData = new MutableLiveData<>();
password = new MutableLiveData<>();
}

public void onLogin(View view) {
Log.e(TAG, "onLogin: " + username.getValue() + " " + password.getValue() );
driver.setUserName(username.getValue());
driver.setPass(password.getValue());
loginLiveData = driver.login();
}
}

为了更好的错误处理,我实现了 tuto1 的 api 观察器:

ApiObserver.java:

public class ApiObserver<T> implements Observer<DataWrapper<T>> {
private ChangeListener<T> changeListener;

public ApiObserver(ChangeListener<T> changeListener) {
this.changeListener = changeListener;
}

@Override
public void onChanged(@Nullable DataWrapper<T> tDataWrapper) {
if (tDataWrapper != null)
if (tDataWrapper.getApiException() != null)
changeListener.onFail(tDataWrapper.getApiException());
else if (tDataWrapper.getCode() != 0)
changeListener.handleCodes(tDataWrapper.getCode());
else if (!tDataWrapper.getErrorMessage().equals(""))
changeListener.onErrorMessage(tDataWrapper.getErrorMessage());
else
changeListener.onSuccess(tDataWrapper.getData());
}


public interface ChangeListener<T> {
void onSuccess(T dataWrapper);

void onFail(Exception exception);

void handleCodes(int code);

void onErrorMessage(String message);
}
}

在 Activity 中,我对电子邮件和密码使用双向绑定(bind),并且登录按钮从 viewModel 触发 onLogin:

SignInActivity.java:

public class SignInActivity extends AppCompatActivity {

private static final String TAG = SignInActivity.class.getName();
private ActivitySignInBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_sign_in);
Utilities.setHtmlText(R.string.forget_password, binding.forgetPassword);

LoginVModel login = ViewModelProviders.of(this).get(LoginVModel.class);
binding.setLoginModel(login);
binding.setLifecycleOwner(this);

login.loginLiveData.observe(this, new ApiObserver<>(listener));
}

private ApiObserver.ChangeListener<LoginResponse> listener = new ApiObserver.ChangeListener<LoginResponse>() {
@Override
public void onSuccess(LoginResponse dataWrapper) {
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
}

@Override
public void onFail(Exception exception) {
exception.printStackTrace();
CheckInternetConnection.requestFail();
}

@Override
public void handleCodes(int code) {
// TODO: 10/2/2019 implement code handling here
Log.e(TAG, "handleCodes: " + code);
}

@Override
public void onErrorMessage(String message) {
Log.e(TAG, "onErrorMessage: i'm here");
ToastMaker.getInstance().showErrorToast(message);
}
};

}

所以我尝试使用错误的数据登录,因此会触发错误消息,这是控制台日志:

E/driver.itgds.khadametdz.viewmodel.viewmodel.LoginVModel: onLogin: test test
E/driver.itgds.khadametdz.api.requesthandler.GenericRequestHandler: handleError: error handled

所以 toast 没有显示,上面的日志也没有显示,所以请问我做错了什么?

PS:对于通用处理程序中的实时数据,我尝试了 .setValue() 和 .PostValue(),但没有一个得到所需的结果。

编辑:我用这种方法尝试了 View 模型,但它没有改变任何东西。

 public void onLogin(View view) {
Log.e(TAG, "onLogin: " + username.getValue() + " " + password.getValue() );
driver.setUserName(username.getValue());
driver.setPass(password.getValue());
// loginLiveData = driver.login();
loginLiveData.postValue(driver.login().getValue());
}

最佳答案

当你创建 ViewModel 时,你会像这样创建 LiveData

loginLiveData = new MutableLiveData<>();

因此,当您执行此操作时,在 Activity 中

login.loginLiveData.observe(this, new ApiObserver<>(listener));

你听这个新的 MutableLiveData<>();。但是当你用这个替换 LiveData 的引用后

loginLiveData = driver.login();

所以你没有观察到相同的 MutableLiveData。我想问题就出在这里。

关于java - 观察通过改造更改的实时数据不会在更改时触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58218986/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com