-2

與ArrayList的填充ArrayAdapter當我初始化一個ArrayList,的NullPointerException在的AsyncTask

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

然後填寫該列表異步通過輪詢的RSS feed。

當異步調用,onPostExecute S,我通過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()

+0

是檢查第一個元素不爲空不會做出很大的區別第一u能在這之後所有的u檢查的ArrayList不低於檢查ArrayList的大小大於0空在使用這些值之前可以檢查Episode模型類沒有任何空值 –

+0

所以我需要檢查三件事情,我應該在哪裏檢查它們?我以爲Arraylist永遠不會是空的,因爲我確實初始化了它? – Nevermore

+0

我認爲,如果您使用的是異步任務,您的ListView可能沒有按照正確的順序初始化。 –

回答

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(); 
} 

返回新的列表。如果你得到一個網絡錯誤,那麼你會得到一個空列表,這是不爲空。

如果你得到一個出界異常,這是一個邏輯上的錯誤在其他地方

+0

我明白了,我很快就會試一試並回復你,謝謝 – Nevermore

+0

謝謝!這幫助我意識到我需要重新思考我如何處理新對象的分配 – Nevermore

0

檢查數組列表不是空

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

對不起,我還不夠清楚。這不**工作:)(已經嘗試過) – Nevermore

+0

檢查是否(!episodes.isEmpty()) – sasikumar

0

我相信你得到你AsyncTask null響應。在這種情況下,當您將該值分配給您的變量時,它將變爲空,因此將變爲NullPointerException

只需在更新episodes變量的值之前進行空檢查。

@Override 
protected void doInBackground(Void... voids) { 
    List<Episode> newEpisodes = yourNetworkCallHere(); 
    if (newEpisodes != null) { 
     episodes = newEpisodes; 
    } 
} 
+0

這不會更新適配器 –

+0

是的,如果你得到一個空的響應,那麼你沒有任何更新。你做? –

+0

如果響應爲空,您可以隨時清除arraylist。如果那是你想要的。 –

相關問題