3

Parcelable インターフェイスを使用して、あるアクティビティから別のアクティビティにオブジェクトの ArrayList を渡そうとしていますが、ArrayList を渡す先のアクティビティに入ると、一貫して NullPointerException が発生します。

Vitamin.java - 文字列と 2 つの String[] 配列を持つオブジェクトを定義し、Parcelable を実装します。

HealthBenefits.java - 文字列のリストを表示します。文字列が選択されると、Vitamin オブジェクトのリストが検索され、選択された文字列を含むオブジェクトが別の ArrayList に入れられます。この ArrayList は、putParcelableArrayListExtra を介して、VitaminDisplay アクティビティに渡されます。

VitaminDisplay.java - アクティビティに渡されるビタミンの名前に対応する文字列のリストを表示します。

ビタミン.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    
            }
        }
  });
}
}

ビタミン表示.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
4

3 に答える 3

2

を使用して配列を書き込んでいますParcel.writeStringArrayが、を使用してそれらを読み込もうとしていますParcel.readSerializableVitamin書き方に合わせてコンストラクタを変更しますwriteToParcel。これはそれを行う必要があります:

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

writeToParcelまたは、 string 配列をSerializableオブジェクトとして書き込むように変更します。または、配列を a に入れ、Bundleバンドルを書き込んでから読み取ることもできます。

さらに良いことに、 using に切り替えてArrayList<String>ください。これにより、これをより適切にサポートできると思います。

于 2013-04-21T22:23:18.833 に答える
1

頭のてっぺん。配列を取得しようとすると、1 つ欠けています。

する代わりに

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

試す

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

次のようなチェックを追加する必要があります...

Bundle b = getIntent().getExtras();
if(b!=null && b.containsKey("VITAMINS")){
   vitaminsList = b.getParcelableArrayList("VITAMINS");
}
于 2013-04-21T21:45:13.303 に答える
1

もっとある可能性があり、これはあなたが現在抱えている問題ではないかもしれませんが、これは問題です. 追加する前にVitaminDisplay初期化することはありませんArrayList

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());
于 2013-04-21T21:43:08.083 に答える