使用RetroFit调用Rest API时,我收到NullPointerException。 问题是我使用相同的方法和适配器结构与另一个具有相同json结构的调用,但由于某种原因只有这个调用得到NullPointerException,请尝试帮助:
例外日志:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.mad.footstats.data.goals.response.GoalsResponse.getTopGoalsList()' on a null object reference
at com.mad.footstats.ui.fragments.StandingsFragment$2.onResponse(StandingsFragment.java:84)
这是片段,我通过改装调用Rest api:
public class StandingsFragment extends Fragment {
private final static String TAG = "Call Failed";
private StandingsAdapter mStandingsAdapter;
private RecyclerView mRecyclerView;
private ProgressBar mProgressBar;
private String mTournamentId;
private String mRegion;
private String mKey;
private GoalsAdapter mGoalsAdapter;
private AssistsAdapter mAssistsAdapter;
public StandingsFragment(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_standings, container, false);
// Getting the Arguments
Bundle bundle = getArguments();
mTournamentId = bundle.getString("tournament_id");
mRegion = bundle.getString("region");
mKey = bundle.getString("key");
// Showing the Progressbar
mProgressBar = view.findViewById(R.id.standings_progress_bar);
// Creating an instance of the ApiInterface
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
// Calling to get the standings from the API
Call<StandingsResponse> call = apiService.getStandings(mRegion,mTournamentId,mKey);
// Logging the URL Call
Log.wtf("URL Called", call.request().url() + "");
call.enqueue(new Callback<StandingsResponse>() {
@Override
public void onResponse(Call<StandingsResponse> call, Response<StandingsResponse> response) {
generateStandings(response.body().getStandings());
mStandingsAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
}
@Override
public void onFailure(Call<StandingsResponse> call, Throwable t) {
Log.e(TAG, t.toString());
Toast.makeText(getActivity(), R.string.enqueue_failure, Toast.LENGTH_LONG).show();
mProgressBar.setVisibility(View.GONE);
}
});
// Calling to get the Goals from the API
Call<GoalsResponse> goalsCall = apiService.getGoalsLeaders(mRegion,mTournamentId,mKey);
// Logging the URL Call
Log.wtf("URL Called", call.request().url() + "");
goalsCall.enqueue(new Callback<GoalsResponse>() {
@Override
public void onResponse(Call<GoalsResponse> call, Response<GoalsResponse> response) {
generateGoals(response.body().getTopGoalsList());
mGoalsAdapter.notifyDataSetChanged();
}
@Override
public void onFailure(Call<GoalsResponse> call, Throwable t) {
Log.e(TAG, t.toString());
Toast.makeText(getActivity(), R.string.enqueue_failure, Toast.LENGTH_LONG).show();
mProgressBar.setVisibility(View.GONE);
}
});
// Calling to get the Assists from the API
Call<AssistsResponse> assistsCall = apiService.getAssistsLeaders(mRegion,mTournamentId,mKey);
// Logging the URL Call
Log.wtf("URL Called", call.request().url() + "");
assistsCall.enqueue(new Callback<AssistsResponse>() {
@Override
public void onResponse(Call<AssistsResponse> call, Response<AssistsResponse> response) {
generateAssists(response.body().getTopAssists());
mGoalsAdapter.notifyDataSetChanged();
}
@Override
public void onFailure(Call<AssistsResponse> call, Throwable t) {
Log.e(TAG, t.toString());
Toast.makeText(getActivity(), R.string.enqueue_failure, Toast.LENGTH_LONG).show();
}
});
return view;
}
/**
* Method to generate List of standings using RecyclerView with custom adapter
*/
private void generateStandings(final List<Standings> empDataList) {
mRecyclerView = getView().findViewById(R.id.standings_rv);
mStandingsAdapter = new StandingsAdapter(empDataList, R.layout.item_standings, getActivity());
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setAdapter(mStandingsAdapter);
}
/**
* Method to generate List of Goal leaders using RecyclerView with Custom adapter
*/
private void generateGoals(final List<TopGoals> topGoals){
RecyclerView recyclerView = getView().findViewById(R.id.goals_rv);
mGoalsAdapter = new GoalsAdapter(topGoals,R.layout.item_goals, getActivity());
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(mGoalsAdapter);
}
/**
* Method to generate List of assists leaders using RecyclerView with Custom adapter
*/
private void generateAssists(final List<TopAssists> topAssists){
RecyclerView assistsRecyclerView = getView().findViewById(R.id.assists_rv);
mAssistsAdapter = new AssistsAdapter(topAssists,R.layout.item_assists, getActivity());
assistsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
assistsRecyclerView.setAdapter(mAssistsAdapter);
}
此外,以下是从API调用生成的Json示例:
{
"tournament": {
"id": "sr:tournament:136",
"name": "A-League",
"sport": {
"id": "sr:sport:1",
"name": "Soccer"
},
"category": {
"id": "sr:category:34",
"name": "Australia",
"country_code": "AUS"
},
"current_season": {
"id": "sr:season:45280",
"name": "A-League 17\/18",
"start_date": "2017-10-06",
"end_date": "2018-05-28",
"year": "17\/18"
}
},
"season_coverage_info": {
"season_id": "sr:season:45280",
"scheduled": 148,
"played": 143,
"max_coverage_level": "gold",
"max_covered": 140,
"min_coverage_level": "bronze"
},
"top_assists": [{
"assists": 12,
"rank": 1,
"player": {
"id": "sr:player:22132",
"name": "George, Leroy"
},
"team": {
"id": "sr:competitor:5970",
"name": "Melbourne Victory",
"abbreviation": "MEL"
}
}, {
"assists": 10,
"rank": 2,
"player": {
"id": "sr:player:139782",
"name": "Petratos, Dimitri"
},
"team": {
"id": "sr:competitor:2934",
"name": "Newcastle United Jets FC",
"abbreviation": "NEW"
}
}]
如果您需要更多代码,请立即提供。
编辑:这是GoalsResponse.Java:
public class GoalsResponse {
@SerializedName("generated_at")
@Expose
private String mGeneratedAt;
@SerializedName("schema")
@Expose
private String mSchema;
@SerializedName("top_goals")
private List<TopGoals> mTopGoalsList;
public String getGeneratedAt() {
return mGeneratedAt;
}
public void setGeneratedAt(String generatedAt) {
mGeneratedAt = generatedAt;
}
public String getSchema() {
return mSchema;
}
public void setSchema(String schema) {
mSchema = schema;
}
public List<TopGoals> getTopGoalsList() {
return mTopGoalsList;
}
public void setTopGoalsList(List<TopGoals> topGoalsList) {
mTopGoalsList = topGoalsList;
}
Json回复中的TopAssists和TopGoals示例:
{
"tournament": {
"id": "sr:tournament:136",
"name": "A-League",
"sport": {
"id": "sr:sport:1",
"name": "Soccer"
},
"category": {
"id": "sr:category:34",
"name": "Australia",
"country_code": "AUS"
},
"current_season": {
"id": "sr:season:45280",
"name": "A-League 17\/18",
"start_date": "2017-10-06",
"end_date": "2018-05-28",
"year": "17\/18"
}
},
"season_coverage_info": {
"season_id": "sr:season:45280",
"scheduled": 148,
"played": 143,
"max_coverage_level": "gold",
"max_covered": 140,
"min_coverage_level": "bronze"
},
"top_goals": [{
"goals": 32,
"rank": 1,
"player": {
"id": "sr:player:159665",
"name": "Salah, Mohamed"
},
"team": {
"id": "sr:competitor:44",
"name": "Liverpool FC",
"abbreviation": "LIV"
}
}, {
"goals": 30,
"rank": 2,
"player": {
"id": "sr:player:108579",
"name": "Kane, Harry"
},
"team": {
"id": "sr:competitor:33",
"name": "Tottenham Hotspur",
"abbreviation": "TOT"
}
}],
"top_assists": [{
"assists": 12,
"rank": 1,
"player": {
"id": "sr:player:22132",
"name": "George, Leroy"
},
"team": {
"id": "sr:competitor:5970",
"name": "Melbourne Victory",
"abbreviation": "MEL"
}
}, {
"assists": 10,
"rank": 2,
"player": {
"id": "sr:player:139782",
"name": "Petratos, Dimitri"
},
"team": {
"id": "sr:competitor:2934",
"name": "Newcastle United Jets FC",
"abbreviation": "NEW"
}
}]
答案 0 :(得分:1)
你应该做的是,在Retrofit中首先检查响应是否成功,所以将onResponse回调更改为:
goalsCall.enqueue(new Callback<GoalsResponse>() {
@Override
public void onResponse(Call<GoalsResponse> call, Response<GoalsResponse> response) {
if(response.isSuccessful()){
Log.d(TAG, response.body().toString())
generateGoals(response.body().getTopGoalsList());
mmGoalsAdapter.notifyDataSetChanged();
}
else{
Log.d(TAG,"in not successfull" + response.code().toString())
}
}
@Override
public void onFailure(Call<GoalsResponse> call, Throwable t) {
Log.e(TAG, t.toString());
Toast.makeText(getActivity(), R.string.enqueue_failure, Toast.LENGTH_LONG).show();
mProgressBar.setVisibility(View.GONE);
}
});
如果Android方面的一切正常,那么你应该可以在isSuccessful()块中看到Log语句。否则,服务器可能出现问题。
如果有帮助,请告诉我。