Retrofit不会返回响应+ Null Object Reference

时间:2017-09-23 08:25:42

标签: java android json retrofit

我是Retrofit的新手,正在尝试构建一个Android应用程序,以便对在LocalHost上运行的Servlet进行REST查询。

我知道这样的错误是由错误的POJO通过Retrofit接收JSON响应引起的。我在this的帮助下根据我的JSON响应修复了我的POJO。

但不幸的是,错误仍然存​​在。感谢所有帮助。

JSON响应

{"businesses":[{"business_name":"Starbucks","city":"San Francisco","avg.rating":2.0,"neighbourhood":"SOMA","latitude":10.02203,"state":"CA","type":"restaurant","business_id":"2","longitude":10.02203}]}

企业类

public class Businesses {

@SerializedName("businesses")
@Expose
private List<Business> businesses = null;

public Businesses() {}

public Businesses(List<Business> businesses) {
    super();
    this.businesses = businesses;
}

public List<Business> getBusinesses() {
    return businesses;
}

public void setBusinesses(List<Business> businesses) {
    this.businesses = businesses;
}
}

商务舱

 public class Business {

@SerializedName("business_name")
@Expose
private String businessName;
@SerializedName("city")
@Expose
private String city;
@SerializedName("avg.rating")
@Expose
private float avgRating;
@SerializedName("neighbourhood")
@Expose
private String neighbourhood;
@SerializedName("latitude")
@Expose
private Double latitude;
@SerializedName("state")
@Expose
private String state;
@SerializedName("type")
@Expose
private String type;
@SerializedName("business_id")
@Expose
private String businessId;
@SerializedName("longitude")
@Expose
private Double longitude;

public Business() {
}

/**
 *
 * @param businessName
 * @param state
 * @param longitude
 * @param businessId
 * @param latitude
 * @param type
 * @param avgRating
 * @param neighbourhood
 * @param city
 */
public Business(String businessName, String city, float avgRating, String neighbourhood, Double latitude, String state, String type, String businessId, Double longitude) {
    super();
    this.businessName = businessName;
    this.city = city;
    this.avgRating = avgRating;
    this.neighbourhood = neighbourhood;
    this.latitude = latitude;
    this.state = state;
    this.type = type;
    this.businessId = businessId;
    this.longitude = longitude;
}

public String getBusinessName() {
    return businessName;
}

public void setBusinessName(String businessName) {
    this.businessName = businessName;
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public float getAvgRating() {
    return avgRating;
}

public void setAvgRating(float avgRating) {
    this.avgRating = avgRating;
}

public String getNeighbourhood() {
    return neighbourhood;
}

public void setNeighbourhood(String neighbourhood) {
    this.neighbourhood = neighbourhood;
}

public Double getLatitude() {
    return latitude;
}

public void setLatitude(Double latitude) {
    this.latitude = latitude;
}

public String getState() {
    return state;
}

public void setState(String state) {
    this.state = state;
}

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public String getBusinessId() {
    return businessId;
}

public void setBusinessId(String businessId) {
    this.businessId = businessId;
}

public Double getLongitude() {
    return longitude;
}

public void setLongitude(Double longitude) {
    this.longitude = longitude;
}

}

logcat的

FATAL EXCEPTION: main
Process: mdnaseemashraf.yapapp, PID: 20528
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at mdnaseemashraf.yapapp.BusinessActivity$1.onResponse(BusinessActivity.java:73)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:171)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我的Recycler Adapter

public class BusinessRecyclerAdapter extends RecyclerView.Adapter<BusinessRecyclerAdapter.BusinessViewHolder> {

private Businesses yapBusinesses;

public class BusinessViewHolder extends RecyclerView.ViewHolder
{
    public TextView tvBusinessName, tvType, tvCity;
    public RatingBar ratingBar;

    public BusinessViewHolder(View itemView) {
        super(itemView);

        tvBusinessName = (TextView) itemView.findViewById(R.id.tvBusinessName);
        tvType = (TextView) itemView.findViewById(R.id.tvType);
        tvCity = (TextView) itemView.findViewById(R.id.tvCity);
        ratingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);
    }
}

public BusinessRecyclerAdapter(Businesses yapBusinessesIn)
{
    this.yapBusinesses = yapBusinessesIn;
}

@Override
public BusinessRecyclerAdapter.BusinessViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
    View itemView = LayoutInflater.from(parent.getContext())
                                  .inflate(R.layout.list_item_business, parent, false);

    return new BusinessViewHolder(itemView);
}

@Override
public void onBindViewHolder(BusinessRecyclerAdapter.BusinessViewHolder holder, int position)
{
    Business yapBusiness =   yapBusinesses.getBusinesses().get(position);
    holder.tvBusinessName.setText(yapBusiness.getBusinessName());
    holder.tvBusinessName.setText(yapBusiness.getBusinessName());
    holder.tvBusinessName.setText(yapBusiness.getBusinessName());
    holder.ratingBar.setRating(yapBusiness.getAvgRating());
}

@Override
public int getItemCount() {
    return yapBusinesses.getBusinesses().size();
}
}

BusinessActivity

public class BusinessActivity extends AppCompatActivity {

private Businesses yapBusinesses = new Businesses();
private RecyclerView businessRecyclerView;
private BusinessRecyclerAdapter businessRecyclerAdapter;

//RETROFIT
public static final String BASE_URL = "http://192.168.1.4:8080/Yap/";
private static Retrofit retrofit = null;

private final static int APP_ID = 11;
private final static String REQUEST_TYPE = "search";
private final static String FORM = "strict"; //"lenient" or "strict",
private final static String KEYWORDS = "sta";
private final static String CITY = "San";
private final static String STATE = "C";
private final static String TYPE = "restaurant"; //"restaurant", "shop", "hotel", "cafe" & "bar".
//

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_business);

    businessRecyclerView = (RecyclerView) findViewById(R.id.business_recycler_view);

    RecyclerView.LayoutManager businesslayoutManager = new LinearLayoutManager(getApplicationContext());
    businessRecyclerView.setLayoutManager(businesslayoutManager);

    businessRecyclerView.setItemAnimator(new DefaultItemAnimator());

    connectAndGetApiData();
}

public void connectAndGetApiData(){

    if (retrofit == null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    YapApiService yapApiService = retrofit.create(YapApiService.class);

    Call<BusinessResponse> call = yapApiService.getSearchedBusiness(APP_ID, REQUEST_TYPE, FORM,
                                                                    KEYWORDS, CITY, STATE, TYPE);
    call.enqueue(new Callback<BusinessResponse>() {
        @Override
        public void onResponse(Call<BusinessResponse> call, Response<BusinessResponse> response) {

            Businesses businessesIN = response.body().getResults();

            Log.println(Log.INFO, "Response Body", response.body().toString()); //Response Body: mdnaseemashraf.yapapp.BusinessResponse@557a8c2
            Log.println(Log.INFO, "Response Results", response.body().getResults().toString()); //Shows NUll ERROR - No Results?

            businessRecyclerView.setAdapter(new BusinessRecyclerAdapter(businessesIN));

            Log.d("Retrofit Data Tag", "Number of Businesses received: " + businessesIN.getBusinesses().size());

            businessRecyclerView.getAdapter().notifyDataSetChanged();
        }

        @Override
        public void onFailure(Call<BusinessResponse> call, Throwable throwable) {
            Log.e("Retrofit Data Error", throwable.toString());
        }
    });
}
}

BusinessResponse类

public class BusinessResponse
{
@SerializedName("page")
private int page;
@SerializedName("results")
private Businesses results;
@SerializedName("total_results")
private int totalResults;
@SerializedName("total_pages")
private int totalPages;

public int getPage() {
    return page;
}

public void setPage(int page) {
    this.page = page;
}

public Businesses getResults() {
    return results;
}

public void setResults(Businesses results) {
    this.results = results;
}

public int getTotalResults() {
    return totalResults;
}

public void setTotalResults(int totalResults) {
    this.totalResults = totalResults;
}

public int getTotalPages() {
    return totalPages;
}

public void setTotalPages(int totalPages) {
    this.totalPages = totalPages;
}
}

2 个答案:

答案 0 :(得分:0)

我认为此声明导致异常businessRecyclerAdapter = new BusinessRecyclerAdapter(yapBusinesses);。执行此操作时,businesses对象的yapBusinesses变量为null

只需从businessRecyclerView.setAdapter(businessRecyclerAdapter);方法中删除该语句和onCreate语句即可。那应该摆脱异常。

答案 1 :(得分:0)

在初始化yapBusinesses

时,new BusinessRecyclerAdapter(yapBusinesses);商家列表中的内容为空

null适配器BusinessRecyclerAdapter方法

执行getItemCount()检查

这将解决您的问题,请尝试以下代码

@Override
public int getItemCount() {
    if(yapBusinesses.getBusinesses()!=null){
      return yapBusinesses.getBusinesses().size();
    }else{
      return 0;
    }
}