インテントを使用して、あるAndroidアクティビティから別のAndroidアクティビティにオブジェクトを送信する方法は?


849

Intentクラスのメソッドを使用して、カスタムタイプのオブジェクトを1つのアクティビティから別のアクティビティに渡すにはどうすればよいですか?putExtra()


@UMMA-質問を「コミュニティWiki」としてマークし続ける必要はありません。ここを見て:meta.stackexchange.com/questions/11740/...
デイブウェッブ

1
@Paresh:指定したリンクは壊れています。あなたは代替を提供できますか?
アンチプレックス2012年


この回答をご覧ください。 stackoverflow.com/questions/8857546/...
Heitor Colangelo

私はシンプルでエレガントなメソッドstackoverflow.com/a/37774966/6456129を
Yessy

回答:


751

オブジェクトを渡すだけの場合、Parcelableはこのために設計されました。Javaのネイティブシリアライゼーションを使用するよりも少し労力が必要ですが、はるかに高速です(つまり、高速です)。

ドキュメントから、実装方法の簡単な例は次のとおりです。

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

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

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

特定のパーセルから取得するフィールドが複数ある場合は、フィールドを配置したのと同じ順序で(つまり、FIFOアプローチで)実行する必要があることに注意してください。

あなたがオブジェクトを持っていたら実装しParcelable、それはちょうどあなたにそれらを置くことの問題だテントputExtra()

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

次に、getParcelableExtra()使用してそれらを戻すことができます。

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

オブジェクトクラスがParcelableおよびSerializableを実装している場合は、必ず次のいずれかにキャストしてください。

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

14
これは、mDataがintではなくオブジェクト(JSONObjectなど)である場合、どのように実装されますか?
Peter Ajtai

301
これがないとオブジェクトを渡せないのはなぜですか?すでにメモリにあるオブジェクトを渡したいと思います。
ceklock

110
@tecnotronその理由アプリは異なるプロセスにあり、個別のメモリアドレススペースがあります。プロセス内のメモリブロックへのポインタ(参照)を送信するだけでは、別のプロセスで使用できるとは期待できません。
marcinj

12
オブジェクトのクラスを直列化可能またはParceableにできない場合はどうすればよいですか?
Amel Jose

11
@ceklockこれの背後にある理由は次のとおりです。アクティビティが遅れて後でメモリから削除された後、ユーザーが最近のメニューからそれを開いたときに、中断したところにアクティビティを作成する必要があります。同じUIである必要があります。この場合、オブジェクトはメモリにありません。しかし、意図はそうです。
tasomaniac 14年

194

オブジェクトをある種の文字列表現にシリアル化する必要があります。可能な文字列表現の1つはJSONであり、AndroidでJSONとの間でシリアライズする最も簡単な方法の1つは、私に尋ねると、Google GSONを使用することです。

その場合、文字列の戻り値をから(new Gson()).toJson(myObject);取得して取得し、fromJsonそれを使用してオブジェクトに戻します。

ただし、オブジェクトがそれほど複雑でない場合は、オーバーヘッドの価値がなく、代わりにオブジェクトの個別の値を渡すことを検討できます。


19
fiXeddの答えは外部ライブラリを使用せずに同じ問題を解決するので、私は推測していると思いますfiXeddの素晴らしいソリューション)
David Hedlund

5
それは正しいと思います。さらに、JSONはクライアント/サーバーにより適したプロトコルであり、スレッド間ではありません。
mobibob 2010

16
特に悪い考えではありません。Gsonは、送信するすべてのオブジェクトにparcelableを実装するよりもはるかに使いやすいためです。
uvesten

7
私のアプリでgsonを使用しているように、これは本当に簡単で素晴らしい方法です!
Lars

16
ニースの答えは、完全なソリューションは次のようになりますが、String s = (new Gson().toJson(client));当時とCli client = new Gson().fromJson(s, Cli.class);
ホアキンIurchuk

155

インテントを通じてシリアライズ可能なオブジェクトを送信できます

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 

2
Parcelableオブジェクトを意図的に送信することもできます。
tony gil

6
「SerializableはAndroidではコミカルに遅い。実際には多くの場合Borderlineは役に立たない。」見stackoverflow.com/questions/5550670/...
セラフィムの

アクティビティがすでに実行されている場合、startActivity(i)を実行する必要がありますか??私は私が作ることができ、意味の活動Aのコール・アクティビティ・Bを、およびにそのデータを戻す活動A?私は混乱していますか?
フランシスココラレスモラレス2014年

3
@Seraphimのパフォーマンスは、多数のオブジェクトをシリアル化する場合に重要ですが、1つのオブジェクトのシリアル化に1ミリ秒または10ミリ秒かかるかどうかはユーザーにはわかりません。意図的エクストラがすでにあるSerializableがそうでない場合Parcelable、それを作成する手間がかかることはめったにありませんParcelable
Kevin Krumwiede、2015

67

アプリケーション内でデータを渡すことがわかっている場合は、「グローバル」を使用します(静的クラスなど)。

これは、Dianne Hackborn(hackbod-Google Android Software Engineer)がこの件について述べたことでした。

アクティビティが同じプロセスで実行されていることがわかっている場合は、グローバルを介してデータを共有できます。たとえば、グローバルなHashMap<String, WeakReference<MyInterpreterState>> を作成し、新しいMyInterpreterStateを作成すると、一意の名前が付けられ、ハッシュマップに配置できます。その状態を別のアクティビティに送信するには、一意の名前をハッシュマップに入れるだけで、2番目のアクティビティが開始されると、受け取った名前でハッシュマップからMyInterpreterStateを取得できます。


25
ええ、これらのインテントを使用するように指定されているのは奇妙だと思いました。その後、トップエンジニアから、データにはグローバルのみを使用するように言われました。しかし、それは馬の口からまっすぐです。
Richard Le Mesurier、2014

1
ここで弱い屈折はガベージコレクションの犠牲にならないでしょうか?
uLYsseus 2014年

1
@uLYsseusはそれがアイデアだと思っています。アクティビティでの作業が完了したら...関連するアクティビティが破棄されると、GCが可能になります
Peter Ajtai

1
@RichardLeMesurier私も同じことを考えていましたが、ダイアンハックボーンからの上記のGoogleグループの投稿を調べました。彼女は、グローバルの唯一の問題は、暗黙のインテントを使用する場合にのみ発生すると述べています(パッケージの外部でアクティビティを起動する可能性があります) )。Dianneが述べているように、これは理にかなっています。これらのアクティビティは、渡されるカスタムタイプについての知識がほとんどないためです。それを読んだ後、グローバルがそのような状況下でそれほど悪いルートではないかもしれない理由が私に明らかになり、他の人も興味がある場合に備えて共有するつもりでした
BMB

インテントが別のコンピューターに渡されるようになるまで、インテントが過剰に設計されました。これは明らかに、1つのプロセスだけで問題が発生している場合は、何かを行うのに適した方法ではありません。メモリの使用、CPUの使用、バッテリーの使用など、それが好ましくない理由です。最後の1つは特に、後から考えると設計を選択する意図が非常に複雑になっています。彼らが良い考えだと主張する人々がいます、通常「グーグルはそう言った」ので。
Lassi Kinnunen

49

クラスはSerializableまたはParcelableを実装する必要があります。

public class MY_CLASS implements Serializable

完了したら、putExtraでオブジェクトを送信できます

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

エキストラを取得するには、あなたがしなければならないだけです

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

クラスがParcelableを実装する場合、次に

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

それが役に立てば幸いです:D


6
あなたのクラスが実装しなければならないのSerializableは間違っています。クラスはParcelable、たとえば実装することができます。
Marc Plano-Lesay 2013年

ParcelableとSerializable @Kernaldの違いは何ですか?処理時間の点で、より遅くなりますか/ベストプラクティスではありませんか?
gumuruh 2014

一方でSerializable、標準のJavaインタフェースで、ParcelableAndroidの固有です。パフォーマンスの面では、Parcelableは、より効率的である:developerphil.com/parcelable-vs-serializable
マルク・プラノ・Lesay

35

迅速なニーズのための短い答え

1.クラスをSerializableに実装します。

内部クラスがある場合は、それらもSerializableに実装することを忘れないでください。

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2.オブジェクトをIntentに入れます

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3.他のアクティビティクラスでオブジェクトを受け取ります

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");

このリンクを参照してください、stackoverflow.com
questions / 2139134 /…

Parcelableインターフェースを実装することで同じことを実現できます。Parcelableインターフェイスは、コードサイズが大きいため、Serializableと比べて実装に時間がかかります。ただし、Serializableよりも高速で、使用するリソースも少なくなります。
Kwnstantinos Nikoloutsos

27

オブジェクトクラスがを実装している場合、Serializable他に何もする必要はなく、シリアル化可能なオブジェクトを渡すことができます。
それが私が使うものです。


24

クラスにシリアライズ可能を実装する

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

        public void setName(String name) {
           this.name = name;
        }
}

次に、このオブジェクトを意図的に渡すことができます

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

このようなデータを取得できる2番目のアクティビティをint

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

しかし、データが大きくなると、この方法は遅くなります。


16

これを行うには、android BUNDLEを使用できます。

次のようにクラスからバンドルを作成します。

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

次に、このバンドルをINTENTで渡します。次のようにbundleを渡すことでクラスオブジェクトを再作成できます

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

これをカスタムクラスで宣言して使用します。


1
Parcelableの直接的な実装であるIMHOが望ましい。BundleはParcelableを単独で実装するため、自分で実装する際の問題をすべて回避しながら、パフォーマンスを向上させることができます。代わりに、キーと値のペアを使用して、単なる順序に依存するよりもはるかに堅牢なデータを保存および取得できます。
リサディナ2013年

Parcelableは私には複雑に見えますが、上記の回答では、オブジェクトのクラスからtoBundleメソッドを使用しているため、オブジェクトがバンドルに変換され、コンストラクタを使用してバンドルをクラスオブジェクトに変換できます。
om252345 2013年

このソリューションは、インテントを介して単一のオブジェクトを渡す場合にのみ実行可能です。
2014

jsonのようですが、jsonは軽量だと思います。
デビッド

取得したオブジェクトは同じオブジェクトですか、それともコピーですか?
マーカス

16

他のクラスやアクティビティの変数やオブジェクトにアクセスする方法はいくつかあります。

A.データベース

B.共有設定。

C.オブジェクトのシリアル化。

D.共通データを保持できるクラスは、それが依存するCommon Utilitiesという名前にすることができます。

E.インテントとParcelableインターフェイスを介してデータを渡す。

プロジェクトのニーズによって異なります。

A. データベース

SQLiteは、Androidに組み込まれているオープンソースデータベースです。SQLiteは、SQL構文、トランザクション、準備済みステートメントなどの標準のリレーショナルデータベース機能をサポートしています。

チュートリアル-http ://www.vogella.com/articles/AndroidSQLite/article.html

B. 共有設定

ユーザー名を保存するとします。したがって、キーユーザー名と値の値という2つのものが存在することになります。

収納方法

 // Create an object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
 //now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();
 //put your value
 editor.putString("userName", "stackoverlow");

 //commits your edits
 editor.commit();

putString()、putBoolean()、putInt()、putFloat()、putLong()を使用して、目的のdtatypeを保存できます。

フェッチする方法

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

http://developer.android.com/reference/android/content/SharedPreferences.html

C. オブジェクトのシリアル化

オブジェクトのシリアル化は、オブジェクトの状態を保存してネットワーク経由で送信する場合や、目的に使用する場合に使用されます。

Java Beanを使用してフィールドに格納し、そのためにゲッターとセッターを使用する

JavaBeansは、プロパティを持つJavaクラスです。プロパティはプライベートインスタンス変数と考えてください。それらはプライベートなので、クラスの外部からアクセスできる唯一の方法は、クラスのメソッドを使用することです。プロパティの値を変更するメソッドはセッターメソッドと呼ばれ、プロパティの値を取得するメソッドはゲッターメソッドと呼ばれます。

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }


}

を使用して、メールメソッドで変数を設定します。

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

次に、オブジェクトSerialzationを使用してこのオブジェクトをシリアル化し、他のクラスではこのオブジェクトを逆シリアル化します。

シリアライゼーションでは、オブジェクトは、オブジェクトのデータ、およびオブジェクトのタイプとオブジェクトに格納されているデータのタイプに関する情報を含むバイトのシーケンスとして表すことができます。

シリアル化されたオブジェクトがファイルに書き込まれた後、ファイルから読み取って逆シリアル化できます。つまり、オブジェクトとそのデータを表す型情報とバイトを使用して、メモリ内にオブジェクトを再作成できます。

このリンクを参照するためのチュートリアルが必要な場合

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

他のクラスの変数を取得する

D. CommonUtilities

プロジェクトで頻繁に必要となる一般的なデータを含むクラスを自分で作成できます。

サンプル

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. インテントを介したデータの受け渡し

データを渡すこのオプションについては、このチュートリアルを参照してください。

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/


(E)でインテントを介したデータの受け渡しについて言及した優れたチュートリアル。
remrick 2015

15

小包の助けをありがとう、私はもう一つのオプションの解決策を見つけました

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

アクティビティー1

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

アクティビティ2のデータを取得する

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }

1
良い答えですが、コーディング基準を増やしてください... +1をシリアライズ可能にするために+1しますが、Parcellableははるかに高速です...
Amit

13

私はGsonをその強力でシンプルなAPIと共に使用して、アクティビティ間でオブジェクトを送信します。

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

送信したいオブジェクトに追加する2つの関数

使用法

AからBにオブジェクトを送信

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

Bで受信

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

ほぼすべてのプロジェクトで使用しており、パフォーマンスの問題はありません。


おかげで、これは私に複雑化の時間を節約しました。
Hristo Stoyanov

10

私は同じ問題で苦労しました。静的クラスを使用して問題を解決し、必要なデータをHashMapに格納しました。さらに、標準のActivityクラスの拡張を使用して、onCreateとonDestroyのメソッドをオーバーライドし、データ転送とデータ消去を非表示にしています。いくつかのとんでもない設定を変更する必要があります。

注釈:別のアクティビティに渡される一般的なオブジェクトを提供しないことは、お尻の痛みです。それは、ひざまずいて自分自身を撃ち、100メートルを勝ち取ろうとするようなものです。「Parcable」だけでは十分ではありません。それは私を笑わせます...私がこのレイヤーをテクノロジーフリーのAPIに実装したくないので、新しいレイヤーを導入したくはありません...どうしてでしょうか?現代のパラダイム...


9

最初のアクティビティ:

intent.putExtra("myTag", yourObject);

そしてあなたの2番目のものでは:

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

カスタムオブジェクトをシリアライズ可能にすることを忘れないでください。

public class myCustomObject implements Serializable {
...
}

ParcelableはSerializableより優れています!AndroidコードでSerializableを使用しないでください。
Filipe Brito

7

これを行う別の方法は、Applicationオブジェクト(android.app.Application)を使用することです。これをAndroidManifest.xmlファイルで次のように定義します。

<application
    android:name=".MyApplication"
    ...

その後、任意のアクティビティからこれを呼び出し、オブジェクトをApplicationクラスに保存できます。

FirstActivityで:

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

SecondActivityで、次のことを行います。

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

これは、アプリケーションレベルのスコープを持つオブジェクトがある場合、つまり、アプリケーション全体で使用する必要がある場合に便利です。のParcelable方法は、オブジェクトのスコープを明示的に制御したい場合や、スコープが制限されている場合に適しています。

Intentsただし、これを使用することは完全に回避されます。彼らがあなたに合うかどうかはわかりません。これを使用したもう1つの方法はint、オブジェクトの識別子にインテントを介して送信し、Applicationオブジェクトのマップにあるオブジェクトを取得することです。


1
これは、オブジェクトが可変であってもよいので、アプリのライフサイクルに沿って、静的オブジェクトについて話す場合、あなたが働くことがあり、物事を行うには正しい方法ではありませんが、私たちが必要とするいくつかの回は、Webサービスを使用して生成された可能性のあるオブジェクトをpassiingかそこらstackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri、2013年

Map識別子を使用してオブジェクトを格納および取得するアプリケーションスコープを設定することにより、Webサービスから生成されたオブジェクトで正常に使用しました。このアプローチの唯一の実際の問題は、Androidがしばらくするとメモリをクリアするため、onResumeでnullを確認する必要があることです(インテントで渡されたオブジェクトは永続化されていると思いますが、よくわかりません)。それを除けば、これが著しく劣っているようには見えません。
Saad Farooq、2013年

これが最良の答えです。さまざまなアクティビティが同じデータモデルを参照する方法を示しています。これを発見するのに長い時間がかかりました!
Markus、

6

クラスモデル(オブジェクト)にSerializableを実装します。次に例を示します。

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

そしてあなたの最初の活動

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

と2番目のアクティビティ(NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

幸運を!!


6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

データを渡す:

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

データの取得:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");

5

私が見つけた最も簡単な解決策は、ゲッターセッターを使用して静的データメンバーを持つクラスを作成することです。

1つのアクティビティから設定し、別のアクティビティからそのオブジェクトを取得します。

アクティビティA

mytestclass.staticfunctionSet("","",""..etc.);

アクティビティb

mytestclass obj= mytestclass.staticfunctionGet();

1
または、シリアル化可能なクラスを作成して、渡したいものを別のアクティビティに渡します。
UMAR

9
大きな脂肪のあるものを置かないことを忘れないでください。そのオブジェクトの存続期間は、アプリケーションの存続期間と同じになります。また、ビューを保存することはありません。このメソッドは、メモリリークも保証します。
リノ

1
この回答は役に立ちますが、メモリとリソースの最適化という点では優れたソリューションではありません
Atul Bhardwaj '13 / 07/13

1
これは、グローバル変数を導入することでOOPの原則を破ります。それらが設定されているかどうかに関係なく、それらがどの状態にあるかはわかりません。それらは多くのスレッドによって使用され、この複雑さに対処する必要があります。これらの変数を解放するタイミングがわからないため、通常はメモリリークが良好です。アプリケーションの異なるモジュール間でハードダイレクトカップリングが導入されることは言うまでもありません。
アフリカの2014

2
WTF?他の2つはかなり優れています。
IcyFlame

4

putExtra(Serializable ..)およびgetSerializableExtra()メソッドを使用して、クラス型のオブジェクトを渡したり、取得したりできます。クラスをSerializableとしてマークし、すべてのメンバー変数が直列化可能であることも確認する必要があります...


4

Androidアプリケーションを作成する

ファイル>>新規>> Androidアプリケーション

プロジェクト名を入力してください:android-pass-object-to-activity

パッケージ:com.hmkcode.android

他のデフォルトの選択を保持し、完了に到達するまで次へ進みます

アプリの作成を開始する前に、あるアクティビティから別のアクティビティにオブジェクトを送信するために使用するPOJOクラス「Person」を作成する必要があります。クラスがSerializableインターフェースを実装していることに注意してください。

Person.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

2つのアクティビティの2つのレイアウト

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

2つのアクティビティクラス

1)ActivityMain.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2)AnotherActivity.java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}

4

GoogleのGsonライブラリを使用して、オブジェクトを別のアクティビティに渡すことができます。実際には、オブジェクトをjson文字列の形式に変換し、他のアクティビティに渡した後、再びこのようなオブジェクトに再変換します

このようなBeanクラスを考えてみましょう

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Exampleクラスのオブジェクトを渡す必要があります

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

読み取るには、NextActivityで逆の操作を行う必要があります

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

この依存関係をgradleに追加します

compile 'com.google.code.gson:gson:2.6.2'


3

私はこれが遅いことを知っていますが、それは非常に簡単です。クラスにSerializableを実装させるだけです。

public class MyClass implements Serializable{

}

その後、あなたはのような意図に渡すことができます

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

それを得るためにあなたは簡単に電話します

MyClass objec=(MyClass)intent.getExtra("theString");

2

いずれにしても、モデルレイヤーへのゲートウェイとして機能するシングルトンクラス(fxサービス)がある場合、そのクラスの変数にゲッターとセッターを設定することで解決できます。

アクティビティ1:

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

アクティビティ2:

private Service service;
private Order order;

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

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

稼働中:

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

このソリューションでは、問題のオブジェクトのシリアル化やその他の「パッケージ化」は必要ありません。しかし、とにかくこの種のアーキテクチャを使用している場合にのみ有益です。


このアプローチの欠点は何ですか?それはとても論理的でスリムに見えます。私はあなたがそれをすべきではないことをいつも読んでいますが、私は何がうまくいかないかもしれないかについての良い説明を決して得ません。
マーカス

コメントを編集できなくなったため、コピーではなくオブジェクトへの参照を取得する唯一の解決策ではありませんか?コピーではなく、同じオブジェクトを取得する必要があります!
Markus

それにつながる高いカップリングのため、これはやや落胆すると思います。しかし、はい、私が見る限り、このアプローチは、実際のオブジェクトが必要な場合に最も実行可能です。プログラミングではいつものように、やりたいことは何でもできます。注意深くやりたいだけです。このソリューションは私にとってはうまくいきました。私はとにかくそのアーキテクチャを使用しているので、私はそれを好みます。
キタルダ2016

実際、私はApplicationクラスを拡張して、そこに私のデータモデルを保存しました。インテントでは、Applicationクラスから元のオブジェクトを取得するために使用できるデータオブジェクトのIDのみをリレーしました。また、拡張アプリケーションクラスは、データモデルが標準のリスナーの概念を介して変更された場合、データモデルを使用するすべてのオブジェクトに通知します。これは、アプリケーション全体でデータモデルを共有する必要がある私の場合にのみ当てはまることを知っていますが、その場合、完全で静的なクラスやフィールドも不要です!
マーカス

2

オブジェクトをパーセルするための私見がはるかに簡単な方法です。区画化するオブジェクトの上に注釈タグを追加するだけです。

ライブラリの例は、https://github.com/johncarl81/parcelerの下にあります

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

    public Example(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() { return name; }

    public int getAge() { return age; }
}

2

まず、クラスにParcelableを実装 します。次に、このようにオブジェクトを渡します。

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

パッケージ文字列は必要ありません。文字列は両方のアクティビティで同じである必要があります

参照


2

このアクティビティから別のアクティビティを開始し、バンドルオブジェクトを介してパラメータを渡します

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);

別のアクティビティ(YourActivity)で取得する

String s = getIntent().getStringExtra("USER_NAME");

これは単純な種類のデータ型には問題ありません。ただし、アクティビティ間で複雑なデータを渡したい場合は、最初にシリアル化する必要があります。

ここに従業員モデルがあります

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Googleが提供するGson libを使用して、このような複雑なデータをシリアル化できます

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
    String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);

2

コルティンに位置

build.gradleにkotlin拡張機能を追加します。

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

次に、このようなデータクラスを作成します。

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

インテントでオブジェクトを渡す

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

意図を持ってオブジェクトを取得する

val sample = intent.getParcelableExtra("id")

まだ実験的ですか?
ShadeToD

2

最も簡単でJavaの方法は、pojo / modelクラスにシリアライズ可能を実装することです。

Androidのパフォーマンスビューに推奨:モデルを分割可能にする


1

最も簡単なのは、アイテムが文字列である次のコードを使用することです。

intent.putextra("selected_item",item)

受け取りについて:

String name = data.getStringExtra("selected_item");

3
文字列、整数などの場合のみですが、オブジェクトが必要で、静的オブジェクトを使用することのみが可能です。
UMAR
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.