在 AsyncTask 中使用 ArrayList 填充 ArrayAdapter 时出现 NullPointerException
NullPointerException when populating ArrayAdapter with ArrayList in AsyncTask
我初始化一个ArrayList,
ArrayList<Episode> episodes = new ArrayList<Episode>(32);
然后通过轮询 RSS 提要异步填充该列表。
当异步调用 onPostExecute
s 时,我通过 populateList
剧集:
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
populateList(episodes);
}
将 ArrayList
传递到自定义 ArrayAdapter
、EpisodeAdapter
。
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?
检查第一项是否为 null 没有任何意义吗?或者我应该检查 和 检查 ArrayList 的 size()
?
检查数组列表是否为空
if (!episodes.isEmpty()){
episodeAdapter = new EpisodeAdapter(getContext(), R.layout.row_episodes, episodes);
mList.setAdapter(episodeAdapter);
}
我相信您在 AsyncTask
中收到了空响应。在这种情况下,当您将该值分配给 episodes
变量时,它将变为 null,因此 NullPointerException
.
只需在更新 episodes
变量的值之前进行空值检查。
@Override
protected void doInBackground(Void... voids) {
List<Episode> newEpisodes = yourNetworkCallHere();
if (newEpisodes != null) {
episodes = newEpisodes;
}
}
制作新的适配器时崩溃...
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)
这是错误的数据更新方式。
您需要清除列表,然后重新填充,然后通知。
我还建议您 return 来自 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();
}
如果出现网络错误,则会得到一个空列表,该列表不为空。
如果出现越界异常,那是其他地方的逻辑错误
我初始化一个ArrayList,
ArrayList<Episode> episodes = new ArrayList<Episode>(32);
然后通过轮询 RSS 提要异步填充该列表。
当异步调用 onPostExecute
s 时,我通过 populateList
剧集:
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
populateList(episodes);
}
将 ArrayList
传递到自定义 ArrayAdapter
、EpisodeAdapter
。
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?
检查第一项是否为 null 没有任何意义吗?或者我应该检查 和 检查 ArrayList 的 size()
?
检查数组列表是否为空
if (!episodes.isEmpty()){
episodeAdapter = new EpisodeAdapter(getContext(), R.layout.row_episodes, episodes);
mList.setAdapter(episodeAdapter);
}
我相信您在 AsyncTask
中收到了空响应。在这种情况下,当您将该值分配给 episodes
变量时,它将变为 null,因此 NullPointerException
.
只需在更新 episodes
变量的值之前进行空值检查。
@Override
protected void doInBackground(Void... voids) {
List<Episode> newEpisodes = yourNetworkCallHere();
if (newEpisodes != null) {
episodes = newEpisodes;
}
}
制作新的适配器时崩溃...
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)
这是错误的数据更新方式。
您需要清除列表,然后重新填充,然后通知。
我还建议您 return 来自 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();
}
如果出现网络错误,则会得到一个空列表,该列表不为空。
如果出现越界异常,那是其他地方的逻辑错误