web-dev-qa-db-ja.com

ArrayListとパーセル可能なアクティビティの受け渡しを支援

だから私は昨日と最後の夜のほとんどをグーグルしてきたが、サブリストに配列リストを渡す方法について頭を包み込むようには思えない。 primitiveデータ型を渡す多くの例とスニペットがありますが、私が持っているのはtypeaddress(address。以下のJava)。

私はこれについてstackoverflowやウェブ上でたくさんのものを見つけましたが、GeoPointの例に関するものを除いて、多くの注目を集めたものはありませんでした。繰り返しになりますが、GeoPointオブジェクトを2つの整数にフラット化して渡しただけのように見えました。アドレスクラスが整数、浮動小数点数などを含むように拡張される可能性があるため、できません。現時点では、以下のテストアプリは簡単にするために2つの文字列のみです。私はそれで小包のものを動作させることができれば、残りが続くかもしれないと思った。

誰かが非プリミティブオブジェクトのArrayListの実用的な例を投稿したり、このコードを機能させるために以下のコードを追加したりできますか?

[〜#〜] update [〜#〜]:返信/編集後に以下のコードが機能するようになりました。ありがとう!

/* helloParcel.Java */        
       public class helloParcel extends Activity
{
    // holds objects of type 'address' == name and state
    private ArrayList <address> myList;

    @Override
    public void onCreate (Bundle savedInstanceState)
    {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.main);

        Button b1 = (Button) findViewById(R.id.button1);
        b1.setOnClickListener(ocl);

        myList = new ArrayList();
        address frank   = new address ("frank", "florida");
        address mary    = new address ("mary", "maryland");
        address monty   = new address ("monty", "montana");

        myList.add (frank);
        myList.add (mary);
        myList.add (monty);

        // add the myList ArrayList() the the extras for the intent

    }

    OnClickListener ocl = new OnClickListener() 
    {

        @Override
        public void onClick(View v) 
        {
            // fill parceable and launch activity
            Intent intent = new Intent().setClass(getBaseContext (), subActivity.class);

            // for some reason, I remember a posting saying it's best to create a new
            // object to pass.  I have no idea why..
            ArrayList <address> addyExtras = new ArrayList <address>();

            for (int i = 0; i < myList.size(); i++)
                addyExtras.add (myList.get(i));

            intent.putParcelableArrayListExtra ("mylist", addyExtras);
            startActivity(intent);
        }
    };
} 



/* address.Java */
  public class address implements Parcelable
{
    private String name;
    private String state;
    private static String TAG = "** address **";

    public address (String n, String s)
    {
        name = n;
        state = s;
        Log.d (TAG, "new address");
    }

    public address (Parcel in)
   {
    Log.d (TAG, "parcel in");
        name = in.readString ();
        state = in.readString ();
   }

    public String getState ()
    {
        Log.d (TAG, "getState()");
        return (state);
    }

    public String getName ()
    {
        Log.d (TAG, "getName()");
        return (name);
    }

    public static final Parcelable.Creator<address> CREATOR
    = new Parcelable.Creator<address>() 
   {
         public address createFromParcel(Parcel in) 
         {
            Log.d (TAG, "createFromParcel()");
             return new address(in);
         }

         public address[] newArray (int size) 
         {
            Log.d (TAG, "createFromParcel() newArray ");
             return new address[size];
         }
    };

    @Override
   public int describeContents ()
   {
        Log.d (TAG, "describe()");
       return 0;
   }

    @Override
   public void writeToParcel (Parcel dest, int flags)
   {
        Log.d (TAG, "writeToParcel");
       dest.writeString (name);
       dest.writeString (state);
   }

}


/* subActivity.Java */
  public class subActivity extends Activity
{
    private final String TAG = "** subActivity **";
    private ArrayList <address> myList;

    @Override
    protected void onCreate (Bundle savedInstanceState)
    {
       super.onCreate (savedInstanceState);
       Log.d (TAG, "onCreate() in subActivity");

       setContentView(R.layout.subactivity);
       TextView tv1 = (TextView) findViewById(R.id.tv_sub);

       myList = getIntent().getParcelableArrayListExtra ("mylist");
       Log.d (TAG, "got myList");

       for (int i = 0; i < myList.size (); i++)
       {
        address a = myList.get (i);
        Log.d (TAG, "state:" + a.getState ());
        tv1.setText (a.getName () + " is from " + a.getState ());
       }

    }

}
31
wufoo

私はここで多くの問題を見ることができます:

  1. AddressParcelableを使用する理由住所にParcelableを実装してから、次を使用してください。

    _intent.putParcelableArrayListExtra( "addresses", addyExtras );
    _
  2. パーセル可能なオブジェクトには、静的なCREATORが含まれている必要があります。詳細については documentation をご覧ください。

  3. startActivity()を呼び出す前に、実際に意図に余分なものを追加することはありません。ここでの提案については、ポイント1を参照してください。

それを機能させるためには、これらすべての問題に対処する必要があると思います。

23
Mark Allison

Parcelableを実装するのに苦労することなく、はるかに簡単に実行できます... ArrayList(ただし、Listではありません)はSerializableです。したがって、Samが言ったように、putExtra()を使用してリスト全体を配置し、getSerializableExtra()を使用してリストを取得できます。

しかし、もう1つ重要なことを追加します:配列リストに格納するオブジェクトはSerializable...も実装する必要があり、オブジェクトに含まれる可能性のある他のすべての複雑なオブジェクト(あなたの場合はなし)も実装する必要があります(したがって、再帰的です-オブジェクトをシリアル化するには、すべてのフィールドをシリアル化できる必要があります)。

さて、パーセルの配列リストを読み書きするメソッドが既にあるのに、Serializableの代わりにParcelableを実装する理由を自問するかもしれません。まあ...違いはシンプルです-implements Serializableとオプションでprivate static final long serialVersionUID = SOME_CONSTANTを追加するだけで完了です!それが、私がParcelableを決して使用しない理由です-多くのメソッドの継承などの代わりに、文字通り2行のコードでSerializableを使用してこれらのすべてを行うことができます...

8
Dexter

マイクdgは正しいです!

putExtra()およびgetSerializable()は、ArrayList<>カスタムオブジェクトのインターフェイスを実装する必要はありません。私のために働いた!

6
Sam

PutExtraを介してSerializableオブジェクトを渡すことができます。 ArrayListはSerializableを実装します。

6
Mike dg