我得到这个错误java.lang.NullPointerException:尝试在空对象引用'上调用接口方法' java.lang.Object java.util.List.get(int)。当我尝试从列表中获取值或返回它的大小时,我无法找到错误。 首先,我正在使用food2fork中的API,因此我可以根据用户的输入(成分)获得一些食谱。
这是我的界面。
public interface ApiService {
@GET("/search")
Call<List<Recipe>> getRecipes(@Query("api") String api_key, @Query ("q") StringBuilder st);
}
对象&#39;课程食谱
public class Recipe {
@SerializedName("publisher")
private String publisher; //to onoma tou ekdoth
@SerializedName("f2f_url")
private String f2f_url; //to url tis suntaghs sto site food2fork
@SerializedName("title")
private String title; //titlos tis suntaghs
@SerializedName("source_url")
private String source_url; //to url ths suntaghs se html
@SerializedName("recipe_id")
private int recipe_id; //to id ths suntaghs
@SerializedName("image_url")
private String image_url; //to url ths eikonas se jpg
@SerializedName("social_rank")
private double social_rank;
@SerializedName("publisher_url")
private String publisher_url; //to vasiko url tou ekdoth
public String getPublisher() {
return publisher;
}
public String getF2f_url() {
return f2f_url;
}
public String getSource_url() {
return source_url;
}
public String getTitle() {
return title;
}
public int getRecipe_id() {
return recipe_id;
}
public double getSocial_rank() {
return social_rank;
}
public String getImage_url() {
return image_url;
}
public String getPublisher_url() {
return publisher_url;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public void setF2f_url(String f2f_url) {
this.f2f_url = f2f_url;
}
public void setTitle(String title) {
this.title = title;
}
public void setSource_url(String source_url) {
this.source_url = source_url;
}
public void setRecipe_id(int recipe_id) {
this.recipe_id = recipe_id;
}
public void setImage_url(String image_url) {
this.image_url = image_url;
}
public void setSocial_rank(double social_rank) {
this.social_rank = social_rank;
}
public void setPublisher_url(String publisher_url) {
this.publisher_url = publisher_url;
}
public Recipe(String publisher, String f2f_url, String title, String source_url, int recipe_id, String image_url, double social_rank, String publisher_url) {
this.publisher = publisher;
this.f2f_url = f2f_url;
this.title = title;
this.source_url = source_url;
this.recipe_id = recipe_id;
this.image_url = image_url;
this.social_rank = social_rank;
this.publisher_url = publisher_url;
}
}
我的主要课程
public class ResponseMain extends AppCompatActivity {
RecyclerView recyclerView;
public static String getApiKey() {
return API_KEY;
}
//to key API ths selidas pou mas epistrefei to json antikeimeno
private final static String API_KEY = "fe7a73e01ac9abc09db51ebf67019f94";
StringBuilder words;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("TAG", "MPIKA");
setContentView(R.layout.activity_response);
if (API_KEY.isEmpty()) {
Toast.makeText(getApplicationContext(), "Please obtain your API key from food2fork.com first!", Toast.LENGTH_LONG);
return;
}
recyclerView = (RecyclerView) findViewById(R.id.recipes_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
words = addingItems_activity.getWords();
getRetrofitArray();
}
public void getRetrofitArray() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService apiService = retrofit.create(ApiService.class);
Call<List<Recipe>> call = apiService.getRecipes(API_KEY, words);
call.enqueue(new Callback<List<Recipe>>() {
@Override
public void onResponse(Call<List<Recipe>> call, Response <List<Recipe>> response) {
try {
Log.d("Here comes the null exception","get title" + response.body().get(0).getTitle());
List<Recipe> recipes = response.body();
recyclerView.setAdapter(new Recipe_Adapter(recipes, R.layout.list_item_recipe, getApplicationContext()));
}
} catch (Exception e) {
Log.d("onResponse", "There is an error", e);
e.printStackTrace();
}
}
@Override
public void onFailure(Call <List<Recipe>> call,Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
} 如果
,还会从其他活动中添加这些词语(itemList.size() == 1) {
words.append(itemList.get(0));
}else{
for (int i = 0; i < (itemList.size() - 1); i++) {
words.append(itemList.get(i) + "%2C");
//%2C表明它们是分开的成分,我发现它是用来翻译逗号的符号 }
words.append((itemList.get(itemList.size() - 1)));
}
答案 0 :(得分:1)
当您为Call<List<Recipe>>
接口中的方法getRecipes()
定义返回类型为ApiService
时,Retrofit需要来自JSONArray类型的服务器的响应,它应该看起来像 -
[
{
"publisher": "Allrecipes.com",
...
},
...
]
但响应来自服务器正在跟随 -
{
"count": 1,
"recipes": [
{
"publisher": "Allrecipes.com"
...
},
...
]
}
因此,您需要解开编写自定义反序列化程序的响应,或者需要将列表包装到包装类中。
您的包装类可以像 -
public class Recipes{
private List<Recipe> recipes;
private int count;
public List<Recipe> getRecipes() {
return recipes;
}
public void setRecipes(List<Recipe> recipes) {
this.recipes = recipes;
}
}
因此您的ApiService接口方法应返回Call<Recipes>
答案 1 :(得分:0)
所以我通过更改第一个查询标记来解决它,当然还有评论者所说的那个类。我有@QUERY api而不是key。这就是我改变界面的方式:
public interface ApiService {
@GET("api/search/")
Call<RootObject> getMyJSON(@Query("key") String api_key, @Query("q") StringBuilder st);
}
另外,我更改了Rest Class的基本URL,因为我将关键字放在界面
上public class RestClient {
//gia na ginei h epikoinwnia me to API prepei na xrhsimopoihsw ton retrofit builder kai na prosdiorisw
//to url tou service
public static final String BASE_URL = "http://food2fork.com/";
private ApiService apiService;
//"?key=";
//+ addingItems_activity.getApiKey() + "&q=" + addingItems_activity.getWords();
private static Retrofit retrofit = null;
private static Retrofit getRetrofitInstance() {
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static ApiService getApiService()
{
return getRetrofitInstance().create(ApiService.class);
}
}
第一个答案说明了解决方案的其余部分。非常感谢!