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