Я пытаюсь загрузить очень простые данные в формате JSON, сгенерированные веб-сервисом, используя Retrofit
и Gson
, а также пытаюсь реализовать архитектуру MVVM
, но получаю null
значение при вызове данных из ViewModel
: я видел много SO-вопросов (или, может быть, не так много), но не могу понять, где и почему у меня возникают эти проблемы.
Итак, что я имеет это
JSON ОТВЕТ : Это может быть либо это:
{
"ok": [
{
"id": 1,
"username": "test1",
"pass": "123",
"reg_date": "2020-05-20 00:00:00"
}
]
}
, либо это:
{
"error": [
{
"message":"user doesn't exists"
}
]
}
I ' Мы создали соответствующие POJO для каждого типа ответа, которые я опущу для простоты. Но также я создал общий c POJO для обработки ответа (спасибо @ Công Hải)
** POJOGenericResponse. java*
public class POJOGenericResponse{
@SerializedName("ok")
private LiveData<ArrayList<POJOUsr>> user;
@SerializedName("error")
private LiveData<ArrayList<POJOError>> error;
//Constructor and Getters...
}
JsonApi. java
public interface JsonApi {
@GET("SelectAllUsr.php")
Call<LiveData<POJOGenericResponse>> getGenericResponse();
}
Я не знаю, как следует называть этот класс в соответствии с его назначением и соглашениями об именах
RetrofitInstance. java
public class RetrofitInstance {
private static String URL_BASE = "http://192.168.0.35/app_android/webservices/";
private static Retrofit retrofit;
private static Gson gson;
public Retrofit getRetrofitInstance(){
gson = new GsonBuilder().setLenient().create();
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(URL_BASE)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
LoginRepository. java
public class LoginRepository{
private RetrofitInstance retrofitInstance;
private JsonApi jsonApi;
private LiveData<POJOGenericResponse> genericResponse;
private Call<LiveData<POJOGenericResponse>> call;
public LoginRepository() {
retrofitInstance = new RetrofitInstance();
jsonApi = retrofitInstance.getRetrofitInstance().create(JsonApi.class);
call = jsonApi.getRespuestaGenerica();
}
//TODO: This should be done in another class??
public LiveData<POJOGenericResponse> getGenericResponse() {
call.clone().enqueue(new Callback<LiveData<POJOGenericResponse>>() {
@Override
public void onResponse(Call<LiveData<POJOGenericResponse>> call, Response<LiveData<POJOGenericResponse>> response) {
if (response.isSuccessful()) {
genericResponse= response.body();
} else {
//
}
}
@Override
public void onFailure(Call<LiveData<POJOGenericResponse>> call, Throwable t) {
//
}
});
return genericResponse;
}
}
LoginViewModel. java
public class LoginViewModel extends AndroidViewModel {
private RepositorioLogin loginRepository;
private MutableLiveData<POJOGenericResponse> serverResponse;
public ViewModelLogin(@NonNull Application application) {
super(application);
loginRepository = new RepositorioLogin();
serverResponse = new MutableLiveData<>();
}
public void setServerResponse(){
serverResponse.setValue(loginRepository.getGenericResponse().getValue());
}
public LiveData<POJORespuestaGenerica> getServerResponse(){
return serverResponse;
}
}
Здесь должны отображаться данные
FragmentData. java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_data, container, false);
TextView exampleText = v.findViewById(R.id.tv_test);
LoginViewModel loginViewModel = new ViewModelProvider(requireActivity()).get(LoginViewModel.class);
loginViewModel.getServerResponse().observe(requireActivity(), new Observer<POJORespuestaGenerica>() {
@Override
public void onChanged(POJOGenericResponse pojoGenericResponse) {
if (pojoGenericResponse.getUser() != null) {
exampleText.setText(pojoGenericResponse.getUser().getValue().get(0).getUsername());
}
if (pojoGenericResponse.getError() != null) {
exampleText.setText(pojoGenericResponse.getError().getValue().get(0).getMensaje());
}
}
});
При отладке я получаю ошибку
response = Не удается найти локальную переменную 'response' serverResponse.setValue (loginRepository.getGenericResponse (). GetValue ()); \ n = java .lang.NullPointerException response = Не удается найти локальную переменную 'response'
, которые описывают проблему сами по себе, но не могут ее решить.
Также любые рекомендации по реализации архитектуры MVVM
будет очень признателен.
Заранее большое спасибо