Java 无法通过改装从webservice获取数据

Java 无法通过改装从webservice获取数据,java,android,gson,retrofit,Java,Android,Gson,Retrofit,我正在尝试加载一些JSON格式的非常简单的数据,这些数据是由Web服务生成的,使用改型和Gson并尝试实现MVVM体系结构,但从视图模型调用数据时,我得到了一个null值: 我已经看到了很多问题(或者可能不太多),但不知道我在哪里以及为什么会遇到这些问题 所以,我得到的是这个 JSON响应:这可以是: { "ok": [ { "id": 1, "username": "test1", "pass":

我正在尝试加载一些JSON格式的非常简单的数据,这些数据是由Web服务生成的,使用
改型
Gson
并尝试实现
MVVM
体系结构,但从
视图模型
调用数据时,我得到了一个
null
值: 我已经看到了很多问题(或者可能不太多),但不知道我在哪里以及为什么会遇到这些问题

所以,我得到的是这个

JSON响应:这可以是:

{
    "ok": [
        {
            "id": 1,
            "username": "test1",
            "pass": "123",
            "reg_date": "2020-05-20 00:00:00"
        }
    ]
}
或者这个:

{
    "error": [
        {
            "message":"user doesn't exists"
        }
    ]
}
我已经为每种响应类型创建了相应的POJO,为了简单起见,我将省略它。但我还创建了一个通用的POJO来处理响应(感谢@CôH)ải、 )

**pojogenericsponse.java*

public class POJOGenericResponse{
    @SerializedName("ok")
    private LiveData<ArrayList<POJOUsr>> user;
    @SerializedName("error")
    private LiveData<ArrayList<POJOError>> error;

    //Constructor and Getters...
}
LoginRepository.java

public interface JsonApi {
    @GET("SelectAllUsr.php")
    Call<LiveData<POJOGenericResponse>> getGenericResponse();
}
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;
    }
}
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;
    }
}
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;
    }
}
    @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());
                }
            }
        });
公共类登录回复{
私人改装实例;
私人JsonApi JsonApi;
私有LiveData genericResponse;
私人通话;
公共登录还原(){
RefughtInstance=新的RefughtInstance();
jsonApi=RefughtInstance.getRefughtInstance().create(jsonApi.class);
call=jsonApi.getRespuestaGenerica();
}
//TODO:这应该在另一节课上完成??
public LiveData getGenericResponse(){
call.clone().enqueue(新回调()命令){
@凌驾
公共void onResponse(调用、响应){
if(response.issusccessful()){
genericResponse=response.body();
}否则{
//
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
//
}
});
返回一般响应;
}
}
LoginViewModel.java

public interface JsonApi {
    @GET("SelectAllUsr.php")
    Call<LiveData<POJOGenericResponse>> getGenericResponse();
}
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;
    }
}
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;
    }
}
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;
    }
}
    @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());
                }
            }
        });
公共类LoginViewModel扩展了AndroidViewModel{
私人寄存学;
私有MutableLiveData服务器响应;
公共ViewModelLogin(@NonNull应用程序){
超级(应用);
loginRepository=新的RepositorioLogin();
serverResponse=new MutableLiveData();
}
public void setServerResponse(){
serverResponse.setValue(loginRepository.getGenericResponse().getValue());
}
公共LiveData getServerResponse(){
返回服务器响应;
}
}
这里应该显示数据

FragmentData.java

public interface JsonApi {
    @GET("SelectAllUsr.php")
    Call<LiveData<POJOGenericResponse>> getGenericResponse();
}
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;
    }
}
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;
    }
}
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;
    }
}
    @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());
                }
            }
        });
@覆盖
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
视图v=充气机。充气(R.layout.fragment_数据,容器,错误);
TextView示例text=v.findviewbyd(R.id.tv_测试);
LoginViewModel LoginViewModel=newviewmodelprovider(requireActivity()).get(LoginViewModel.class);
loginViewModel.getServerResponse().observe(Requiresponsibility(),new Observer()){
@凌驾
更改后的公共无效(POJOGenericResponse POJOGenericResponse){
if(pojoGenericResponse.getUser()!=null){
例如text.setText(pojoGenericResponse.getUser().getValue().get(0.getUsername());
}
if(pojoGenericResponse.getError()!=null){
例如text.setText(pojoGenericResponse.getError().getValue().get(0.getMensaje());
}
}
});
调试时,我得到的错误是

response=找不到局部变量'response'serverResponse.setValue(loginRepository.getGenericResponse().getValue());\n=java.lang.NullPointerException response=找不到局部变量“response”

它们自己描述了问题,但无法解决它

此外,任何关于
MVVM
体系结构实现的建议都将非常感谢


在此之前,非常感谢

看起来这是一个错误的位置--

public LiveData getGenericResponse(){
call.clone().enqueue(新回调()命令){
@凌驾
公共void onResponse(调用、响应){
if(response.issusccessful()){
genericResponse=response.body();
}否则{
//
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
//
}
});
返回一般响应;
}
因此,
onResponse
是一个异步调用,您将立即从该方法返回
returngenericsponse;


与其从这个方法中得到一个返回值,不如将它改为void,并直接在
private LiveData genericResponse;

上观察,这澄清了很多。谢谢!!我现在正在处理你答案的第二部分,我不太清楚,我非常不清楚这个XD。它不再崩溃,但不显示任何数据。我应该在哪里观察在相同的
ViewModel
Repository
或片段中提供
genericResponse
?我想我遗漏了一些步骤。您应该在片段/活动中观察它,无论您使用哪个。