2013-04-21 101 views
3

我想通過一個活動傳遞一個對象的ArrayList到另一個使用Parcelable接口,但是當我輸入我傳遞的活動時,我始終得到一個NullPointerException數組列表。將ArrayList <CustomObject>傳遞給另一個活動,獲取NullPointerException

Vitamin.java - 定義與串和兩個字符串[]陣列的對象,實現Parcelable

HealthBenefits.java - 顯示字符串的列表。當選擇一個字符串時,將搜索維生素對象列表,並將包含所選字符串的對象放入另一個ArrayList。這個ArrayList然後通過putParcelableArrayListExtra傳遞給VitaminDisplay活動。

VitaminDisplay.java - 顯示與傳遞給活動的維生素名稱對應的字符串列表。

Vitamin.java

public class Vitamin implements Parcelable{ 

String theName; 
String[] theFoods, theBenefits; 

public Vitamin(String name, String[] benefits, String[] foods) 
{ 
    theName = name; 
    theBenefits = benefits; 
    theFoods = foods; 
} 

private Vitamin(Parcel in){ 
    theName = in.readString(); 
    ArrayList<String> tempBenefits = new ArrayList<String>(); 
    tempBenefits = (ArrayList<String>) in.readSerializable(); 
    ArrayList<String> tempFoods = new ArrayList<String>(); 
    tempFoods = (ArrayList<String>) in.readSerializable(); 

    //convert from ArrayList<String> to String[] 
    theBenefits = new String[tempBenefits.size()]; 
    theFoods = new String[tempFoods.size()]; 
    theBenefits = tempBenefits.toArray(theFoods); 
    theFoods = tempFoods.toArray(theFoods); 
} 

public String getName(){ 
    return theName; 
} 

public String[] getBenefit(){ 
    return theBenefits; 
} 

public String[] getFoods(){ 
    return theFoods; 
} 

@Override 
public int describeContents() { 
    // TODO Auto-generated method stub 
    return 0; 
} 

@Override 
public void writeToParcel(Parcel out, int flags) { 
    // TODO Auto-generated method stub 
    out.writeString(theName); 
    out.writeStringArray(theBenefits); 
    out.writeStringArray(theFoods); 
} 

public static final Parcelable.Creator<Vitamin> CREATOR = new Parcelable.Creator<Vitamin>() { 
    public Vitamin createFromParcel(Parcel in) { 
     return new Vitamin(in); 
    } 

    public Vitamin[] newArray(int size) { 
     return new Vitamin[size]; 
    } 
}; 
} 

HealthBenefits.java

public class HealthBenefits extends Activity{ 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.health_benefits_layout); 

    ListView benefits = (ListView) findViewById(R.id.listView1); 
    benefits.setTextFilterEnabled(true); 
    ArrayAdapter<CharSequence> aa = ArrayAdapter.createFromResource(this, R.array.benefits, android.R.layout.simple_list_item_1); 
    benefits.setAdapter(aa); 

    final ArrayList<Vitamin> vitamins = new ArrayList<Vitamin>(); 
    String[] foods1 = {"Pork", "Whole grain", "Legumes", "Nuts and seeds"}; 
    String[] vitaBenefits1 = {"Improve nerve function", "Improve metabolism"}; 
    vitamins.add(new Vitamin("Vitamin B1", vitaBenefits1, foods1)); 

    String[] vitaBenefits13 = {"Improve circulatory function"}; 
    String[] foods13 = {"Leafy green vegetables"}; 
    vitamins.add(new Vitamin("Vitamin K", vitaBenefits13, foods13)); 

     //...more vitamin objects added to the list, omitted for brevity 

    benefits.setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, 
      int position, long id) { 
      // When clicked, show a toast with the TextView text 
      ArrayList<Vitamin> listToDisplay = new ArrayList<Vitamin>(); 

      if(position == 1) 
      { 
      //code specific to first list item  
        for(int i = 0;i < vitamins.size();i++){ 
         if(vitamins.get(i).getBenefit().equals("Improve immune system")) { 
          listToDisplay.add(vitamins.get(i)); 
         } 

        } 
        Intent myIntent = new Intent(view.getContext(), VitaminDisplay.class); 
        myIntent.putParcelableArrayListExtra("VITAMINS", listToDisplay); 
        startActivityForResult(myIntent, 0); 
      } 

      if(position == 2) 
      { 
      //code specific to 2nd list item  
      } 
     } 
    }); 
} 
} 

VitaminDisplay.java

public class VitaminDisplay extends Activity{ 

ArrayList<Vitamin> vitaminsList; 
ArrayList<String> displayList; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.health_benefits_layout); 

    vitaminsList = getIntent().getExtras().getParcelableArrayList("VITAMINS"); 
      displayList = new ArrayList<String>(); 

    for(int i = 0;i < vitaminsList.size();i++){ 
     displayList.add(vitaminsList.get(i).getName()); 
     Log.d("VitaminDisplay", vitaminsList.get(i).getName()); 
    } 

    //displayList = new ArrayList<String>(); 
    //displayList.add("test"); 

    ListView benefits = (ListView) findViewById(R.id.listView1); 
    benefits.setTextFilterEnabled(true); 
    ArrayAdapter<String> aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, displayList); 
    benefits.setAdapter(aa); 
} 

} 

我是如果我已經在Vitamin.java中實現了Parcelable類,可能會出現異常,但我還沒有找到解決方案。有什麼建議麼?

下面是完整的logcat:

E/AndroidRuntime(1958): FATAL EXCEPTION: main 

04-21 21:55:08.963: E/AndroidRuntime(1958): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.heartsmart/com.example.heartsmart.VitaminDisplay}: java.lang.NullPointerException 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.ActivityThread.access$600(ActivityThread.java:141) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Handler.dispatchMessage(Handler.java:99) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Looper.loop(Looper.java:137) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.ActivityThread.main(ActivityThread.java:5041) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at java.lang.reflect.Method.invoke(Method.java:511) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at dalvik.system.NativeStart.main(Native Method) 
04-21 21:55:08.963: E/AndroidRuntime(1958): Caused by: java.lang.NullPointerException 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:60) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Parcel.readSerializable(Parcel.java:2139) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at com.example.heartsmart.Vitamin.<init>(Vitamin.java:23) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at com.example.heartsmart.Vitamin.<init>(Vitamin.java:20) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at com.example.heartsmart.Vitamin$1.createFromParcel(Vitamin.java:62) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at com.example.heartsmart.Vitamin$1.createFromParcel(Vitamin.java:1) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Parcel.readParcelable(Parcel.java:2103) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Parcel.readValue(Parcel.java:1965) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Parcel.readListInternal(Parcel.java:2235) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Parcel.readArrayList(Parcel.java:1655) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Parcel.readValue(Parcel.java:1986) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Parcel.readMapInternal(Parcel.java:2226) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Bundle.unparcel(Bundle.java:223) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.os.Bundle.containsKey(Bundle.java:271) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at com.example.heartsmart.VitaminDisplay.onCreate(VitaminDisplay.java:23) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.Activity.performCreate(Activity.java:5104) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 
04-21 21:55:08.963: E/AndroidRuntime(1958):  ... 11 more 
+0

什麼生產線生產NPE? – 2013-04-21 21:38:44

+0

editted以顯示異常:04-21 20:59:26.203:E/AndroidRuntime(1093):java.lang.RuntimeException:無法啓動活動ComponentInfo {com.example.heartsmart/com.example.heartsmart.VitaminDisplay}: java.lang.NullPointerException – 2013-04-21 21:42:12

+0

還有更多的logcat。類似於'由com.your.package.name(java行號引起)'這會告訴你在 – codeMagic 2013-04-21 21:45:32

回答

1

頂我的頭前初始化ArrayList。當你嘗試獲取數組時,有一件事是丟失的。

而不是做

vitaminsList = getIntent().getParcelableArrayListExtra("VITAMINS"); 

嘗試

vitaminsList = getIntent().getExtras.getParcelableArrayList("VITAMINS"); 

你應該增加更多的檢查,就像...

Bundle b = getIntent().getExtras(); 
if(b!=null && b.containsKey("VITAMINS")){ 
    vitaminsList = b.getParcelableArrayList("VITAMINS"); 
} 
+0

更改,謝謝。不幸的是仍然收到NullPointerException。 – 2013-04-21 21:54:06

+0

在將它傳遞給第二個活動之前,請確保您的數組列表不爲空。 – Sharj 2013-04-21 21:55:29

+0

通過添加一些元素來檢查數組,然後傳遞並將大小打印到日誌中。不幸的是,我不希望這會是解決方案。 – 2013-04-21 22:01:09

1

可能會有更大,這可能不是當前所遇到的問題,但是這是一個問題。在​​你從來沒有試圖將其添加到它

ArrayList<String> displayList; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.health_benefits_layout); 

vitaminsList = getIntent().getParcelableArrayListExtra("VITAMINS"); 
for(int i = 0;i < vitaminsList.size();i++){ 
    displayList.add(vitaminsList.get(i).getName()); // displayList isn't initialized 

更改爲

ArrayList<String> displayList = new ArrayList<String>(); // Change this here 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

super.onCreate(savedInstanceState); 
setContentView(R.layout.health_benefits_layout); 

vitaminsList = getIntent().getParcelableArrayListExtra("VITAMINS"); 
for(int i = 0;i < vitaminsList.size();i++){ 
    displayList.add(vitaminsList.get(i).getName()); 
+0

啊,那很尷尬。感謝您的支持 – 2013-04-21 21:46:49

+1

不客氣...發生了。請接受答案,以便它可以更容易 – codeMagic 2013-04-21 21:49:59

+0

即使在使用此修復程序時,我仍然收到NullPointerException。 – 2013-04-21 21:58:52

2

你正在寫使用Parcel.writeStringArray您的陣列,但想讀他們使用Parcel.readSerializable。更改您的Vitamin構造函數以匹配您如何編寫writeToParcel。這應做到:

private Vitamin(Parcel in){ 
    theName = in.readString(); 
    theBenefits = in.createStringArray(); 
    theFoods = in.createStringArray(); 
} 

另外,修改writeToParcel到字符串數組寫成Serializable對象。或者,您可以將陣列放入Bundle中,然後寫入並讀取該包。

更好的是,切換到使用ArrayList<String>,我認爲這提供了更好的支持。

相關問題