web-dev-qa-db-ja.com

Androidで1つのアクティビティから別のアクティビティにオブジェクトを渡すにはどうすればよいですか?

アプリ内の複数のアクティビティで1つのオブジェクトを使用できる必要があり、それは同じオブジェクトである必要があります。これを行う最良の方法は何ですか?

オブジェクトを「パブリックスタティック」にして、他のアクティビティからアクセスできるようにしようとしましたが、何らかの理由でこれが切り捨てられません。これを行う別の方法はありますか?

122
mtmurdock

意図したオブジェクトを作成する場合、2つのアクティビティ間でオブジェクトを渡すために次の2つの方法を利用できます。

putParcelable

putSerializable

クラスに Parcelable または Serializable を実装させることができます。その後、アクティビティ全体でカスタムクラスを渡すことができます。これは非常に便利です。

ここに私が使用しているコードの小さなスニペットがあります

CustomListing currentListing = new CustomListing();
Intent i = new Intent();
Bundle b = new Bundle();
b.putParcelable(Constants.CUSTOM_LISTING, currentListing);
i.putExtras(b);
i.setClass(this, SearchDetailsActivity.class);
startActivity(i);

そして、新たに開始されたアクティビティコードでは、このようなものになります...

Bundle b = this.getIntent().getExtras();
if (b != null)
    mCurrentListing = b.getParcelable(Constants.CUSTOM_LISTING);
139
anargund

Application のサブクラスを作成して、そこに共有オブジェクトを保存できます。アプリケーションオブジェクトは、アクティブなコンポーネントがある限り、アプリの存続期間中存在する必要があります。

アクティビティから、getApplication()を介してアプリケーションオブジェクトにアクセスできます。

37
Erich Douglass

この回答は、渡されるオブジェクトにネストされたクラス構造がある状況に固有です。ネストされたクラス構造では、ParcelableまたはSerializeableにするのは少し面倒です。そして、オブジェクトをシリアル化するプロセスは Androidでは効率的ではありません です。以下の例を考えてください。

class Myclass    {
  int a;
  class SubClass    {
       int b;
  }
}

Googleの GSONライブラリ を使用すると、オブジェクトを直接JSON形式の文字列に解析し、使用後にオブジェクト形式に戻すことができます。例えば、

MyClass src = new MyClass();
Gson gS = new Gson();
String target = gS.toJson(src); // Converts the object to a JSON String

これで、このStringを、アクティビティを意図したStringExtraとしてアクティビティ間で渡すことができます。

Intent i = new Intent(FromActivity.this, ToActivity.class);
i.putExtra("MyObjectAsString", target);

次に、受信アクティビティで、文字列表現から元のオブジェクトを作成します。

String target = getIntent().getStringExtra("MyObjectAsString");
MyClass src = gS.fromJson(target, MyClass.class); // Converts the JSON String to an Object

元のクラスをクリーンで再利用可能に保ちます。とりわけ、これらのクラスオブジェクトがWebからJSONオブジェクトとして作成される場合、このソリューションは非常に効率的で時間を節約できます。

UPDATE


上記の方法はほとんどの状況で機能しますが、明らかなパフォーマンス上の理由から、オブジェクトの受け渡しにAndroidのバンドルされた追加システムに依存しないでください。このプロセスを柔軟かつ効率的にする多くのソリューションがありますが、ここにいくつかあります。それぞれに長所と短所があります。

  1. イベントバス
  2. オットー
35
Subin Sebastian

たぶんそれは不人気な答えかもしれませんが、過去には、アクティビティを通して永続化したいオブジェクトへの静的な参照を持つクラスを使用していました。そう、

public class PersonHelper
{
    public static Person person;
}

Parcelableインターフェイスパスを試しましたが、いくつかの問題が発生し、コードのオーバーヘッドが魅力的ではありませんでした。

6
Chris Stewart

アクセスする必要のあるデータの種類によって異なります。 Activitysを越えて持続する必要がある何らかの種類のデータプールがある場合、Erichの答えは進むべき道です。あるアクティビティから別のアクティビティにいくつかのオブジェクトを渡す必要がある場合は、Serializableを実装し、Intentのエクストラに渡して新しいActivityを開始できます。

5
CaseyB

オブジェクトはParcelableインターフェイスを実装することもできます。次に、Bundle.putParcelable()メソッドを使用して、意図内のアクティビティ間でオブジェクトを渡すことができます。

Photostream アプリケーションはこのアプローチを使用しており、参照として使用できます。

5
Fedor