在AsyncTask中使用ArrayList填充ArrayAdapter时出现NullPointerException

时间:2017-05-21 16:12:31

标签: android arraylist android-asynctask nullpointerexception android-arrayadapter

我初始化一个ArrayList,

    ArrayList<Episode> episodes = new ArrayList<Episode>(32);

然后通过轮询RSS提要以异步方式填充该列表。

当异步通话onPostExecute时,我通过剧集传递populateList

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            populateList(episodes);
        }

ArrayList传递给自定义ArrayAdapterEpisodeAdapter

    public void populateList(ArrayList<Episode> episodes) {
        episodeAdapter = new EpisodeAdapter(getContext(), R.layout.row_episodes, episodes);
        mList.setAdapter(episodeAdapter);
    }

感谢新的崩溃报告,我开始意识到经常导致NullPointerExceptions 的频率......(但我似乎无法在本地重现它!) 。

根据我当时使用的修复程序,堆栈跟踪看起来像这样:

java.lang.NullPointerException: 
  at android.view.LayoutInflater.from(LayoutInflater.java:234)
  at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:178)
  at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:163)
  at com.workingagenda.democracydroid.Adapters.EpisodeAdapter.<init>(EpisodeAdapter.java:47)
  at com.workingagenda.democracydroid.MainActivity$PodcastFragment.populateList(MainActivity.java:236)
  at com.workingagenda.democracydroid.MainActivity$PodcastFragment$GetAudioFeed.onPostExecute(MainActivity.java:590)
  at com.workingagenda.democracydroid.MainActivity$PodcastFragment$GetAudioFeed.onPostExecute(MainActivity.java:545)

我已经尝试了很多东西来减少崩溃次数,即在我调用populateList之前检查,ArrayList episodes .size()不是0(这总是我想因为我把它初始化为32)。或者,在populateList内,我检查第一项是否为null(例如:

        if (episodes.get(0) != null){
            episodeAdapter = new EpisodeAdapter(getContext(), R.layout.row_episodes, episodes);
            mList.setAdapter(episodeAdapter);
        }

但有时我会得到一个java.lang.IndexOutOfBoundsException(但有时仍然是NullPointerException

如果剧集由于某种原因没有被异步调用填充,我如何防止应用程序崩溃?

我应该在适配器的getView()方法中检查null吗?

检查第一项是否没有任何意义?或者我应该检查 检查ArrayList的size()吗?

3 个答案:

答案 0 :(得分:1)

制作新适配器时会崩溃......

java.lang.NullPointerException: 
    at android.view.LayoutInflater.from(LayoutInflater.java:234)
    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:178)
    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:163)
    at com.workingagenda.democracydroid.Adapters.EpisodeAdapter.<init>(EpisodeAdapter.java:47)

更新数据的方法不对。

您需要清除列表,然后重新填充,然后通知。

我还建议您从doInBackground

返回新列表
@Override
protected void doInBackground(List<Episode> episodes) {
    List<Episode> newEpisodes = new ArrayList<>();

    try {
        yourNetworkCallHere();
        newEpisodes.add(...);
    } catch (Exception e) {} 

    return newEpisodes;  // this can't be null 
}

@Override
public void onPostExecute(List<Episode> results) {
    episodes.clear();
    episodes.addAll(results);
    episodeAdapter.notifyDataSetChanged();
} 

如果出现网络错误,则会得到一个空列表,该列表不为空。

如果你遇到越界异常,这是其他地方的逻辑错误

答案 1 :(得分:0)

检查arraylist不是空的

 if (!episodes.isEmpty()){
        episodeAdapter = new EpisodeAdapter(getContext(), R.layout.row_episodes, episodes);
        mList.setAdapter(episodeAdapter);
    }

答案 2 :(得分:0)

我相信你在scale收到空回复。在这种情况下,当您将该值分配给AsyncTask变量时,它将变为空,因此episodes

在更新NullPointerException变量的值之前,只需进行空检查。

episodes