我正在尝试使用Parcelable接口将对象的ArrayList从一个活动传递到另一个活动,但是当我输入我传递给我的ArrayList的活动时,我一直得到一个NullPointerException。
Vitamin.java - 定义一个带有字符串和两个String []数组的对象,实现Parcelable
HealthBenefits.java - 显示字符串列表。选择字符串时,将搜索维生素对象列表,并将包含所选字符串的对象放入另一个ArrayList中。然后通过putParcelableArrayListExtra将此ArrayList传递给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 :(得分: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>
,我认为可以为此提供更好的支持。
答案 1 :(得分:1)
可能会有更多,这可能不是您目前遇到的问题,但这是一个问题。在VitaminDisplay
中,您在尝试添加ArrayList
之前永远不会初始化<{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());
答案 2 :(得分:1)
我的头脑。当你试图获得数组时,有一件事是缺失的。
而不是做
vitaminsList = getIntent().getParcelableArrayListExtra("VITAMINS");
试
vitaminsList = getIntent().getExtras.getParcelableArrayList("VITAMINS");
您应该添加更多支票,例如......
Bundle b = getIntent().getExtras();
if(b!=null && b.containsKey("VITAMINS")){
vitaminsList = b.getParcelableArrayList("VITAMINS");
}