2017-09-23 103 views
-3

我是Retrofit的新手,試圖構建一個Android應用程序來對在LocalHost上運行的Servlet進行REST查詢。Retrofit不返回響應+空對象參考

我知道這樣的錯誤是由不正確的POJO通過Retrofit接收JSON響應引起的。我根據我的JSON響應在this的幫助下修復了我的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) 

我的回收站適配器

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: [email protected] 
      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; 
} 
} 
+0

它將有助於瞭解如何創建'BusinessRecyclerAdapter'對象。 – Titus

+0

添加了我的Business Activity類,該類使用onResponse中提取的數據構建Businesses對象,並進一步使用它構建新的適配器,並將此新適配器設置爲回收視圖。 –

+1

@MDNaseemAshraf查看我的回答 – akhilesh0707

回答

0

我覺得這個說法是造成異常businessRecyclerAdapter = new BusinessRecyclerAdapter(yapBusinesses);。執行此操作時,yapBusinesses對象的businesses變量爲null

只需從onCreate方法中刪除該語句和businessRecyclerView.setAdapter(businessRecyclerAdapter);語句即可。這應該擺脫例外。

0

內,您的yapBusinesses企業名單是在初始化new BusinessRecyclerAdapter(yapBusinesses);

的時間空你BusinessRecyclerAdapter適配器上進行null檢查getItemCount()方法

這將解決您的問題,試試下面的代碼

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

正如我所看到的,空檢查不是問題。 Retrofit沒有迴應。即使是日誌也會給出一個空錯誤。就我所知,企業IN的迴應沒有被退回。 –

+0

請檢查錯誤日誌,它清楚地顯示你的'yapBusinesses.getBusinesses()'爲空 – akhilesh0707

+0

是的。在不進行空初始化的情況下更新所有日誌和文件。等一下。 –