バンドルを介して処理の大部分を行うクラスへの参照を渡す必要があります。
問題は、インテントやコンテキストとは関係がなく、大量の非プリミティブオブジェクトがあることです。クラスをparcelable / serializableにパッケージ化してに渡すにはどうすればよいstartActivityForResult
ですか?
バンドルを介して処理の大部分を行うクラスへの参照を渡す必要があります。
問題は、インテントやコンテキストとは関係がなく、大量の非プリミティブオブジェクトがあることです。クラスをparcelable / serializableにパッケージ化してに渡すにはどうすればよいstartActivityForResult
ですか?
回答:
CommonsWareの重要な「なぜ」という質問だけでなく、「何をするのか」という質問にも答える必要があります。合格していますか?
実際には、バンドルを通過できるのはプレーンデータのみです。それ以外はすべて、そのデータの意味または参照先の解釈に基づいています。文字通りオブジェクトを渡すことはできませんが、できることは次の3つのうちの1つです。
1)オブジェクトを構成データに分解できます。もう一方の端に同じ種類のオブジェクトの知識がある場合、シリアル化されたデータからクローンを組み立てることができます。これが、一般的なタイプのほとんどがバンドルを通過する方法です。
2)不透明なハンドルを渡すことができます。同じコンテキスト内でそれを渡す場合(理由を尋ねる人もいるかもしれませんが)、それを呼び出しまたは逆参照できるハンドルになります。しかし、それをBinderを介して別のコンテキストに渡すと、そのリテラル値は任意の数になります(実際、これらの任意の数は起動から順番にカウントされます)。何もすることはできませんが、それを元のコンテキストに戻し、Binderがそれを元のハンドルに変換して再び使用できるようになるまで、それを追跡します。
3)ファイル記述子や特定のos /プラットフォームオブジェクトへの参照などのマジックハンドルを渡すことができます。正しいフラグを設定すると、バインダーは実際に使用できる受信者の同じリソースを指すクローンを作成します。もう一方の端。しかし、これはごく少数のタイプのオブジェクトに対してのみ機能します。
ほとんどの場合、クラスを渡して、もう一方の端で追跡し、後でそれを返せるようにするか、シリアル化された構成データからクローンを作成できるコンテキストに渡すか、またはうまくいかないことをしようとしていて、アプローチ全体を再考する必要があります。
Gsonを使用してオブジェクトをJSONObjectに変換し、バンドルで渡すこともできます。私にとっては、これを行うために見つけた最もエレガントな方法でした。パフォーマンスへの影響をテストしていません。
初期活動中
Intent activity = new Intent(MyActivity.this,NextActivity.class);
activity.putExtra("myObject", new Gson().toJson(myobject));
startActivity(activity);
次のアクティビティで
String jsonMyObject;
Bundle extras = getIntent().getExtras();
if (extras != null) {
jsonMyObject = extras.getString("myObject");
}
MyObject myObject = new Gson().fromJson(jsonMyObject, MyObject.class);
Parcelableインタフェースは意図してオブジェクトを渡すための良い方法です。
カスタムオブジェクトをParcelableにするにはどうすればよいですか?Parcelableの使用方法についてはかなり良い答えです
公式のGoogleドキュメントにも例が含まれています
グローバルなアプリケーション状態を使用できます。
更新:
これをカスタマイズしてAndroidManifest.xmlに追加します。
<application android:label="@string/app_name" android:debuggable="true" android:name=".CustomApplication"
そして、あなたのプロジェクトに次のようなクラスがあります:
package com.example;
import android.app.Application;
public class CustomApplication extends Application {
public int someVariable = -1;
}
また、「任意のアクティビティまたはサービスからgetApplication()を介してアクセスできる」ため、次のように使用します。
CustomApplication application = (CustomApplication)getApplication();
application.someVariable = 123;
お役に立てば幸いです。
また、あなたのオブジェクトを作ることができるシリアライズおよびバンドルの使用getSerializableとputSerializable方法を。
可能な解決策:
Bundle bundle = new Bundle();
bundle.putSerializable("key", new CustomObject());
クラスCustomObject:
class CustomObject implements Serializable{
private SubCustomObject1 sc1;
private SubCustomObject2 sc2;
}
サブカスタムオブジェクト:
class SubCustomObject1 implements Serializable{ }
class SubCustomObject2 implements Serializable{ }
バンドルを介してオブジェクトを送信するもう1つの方法は、サンプルコードを使用することbundle.putByteArray
です。
public class DataBean implements Serializable {
private Date currentTime;
public setDate() {
currentTime = Calendar.getInstance().getTime();
}
public Date getCurrentTime() {
return currentTime;
}
}
DataBeanのオブジェクトをバンドルに配置します。
class FirstClass{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...
//When you want to start new Activity...
Intent dataIntent =new Intent(FirstClass.this, SecondClass.class);
Bundle dataBundle=new Bundle();
DataBean dataObj=new DataBean();
dataObj.setDate();
try {
dataBundle.putByteArray("Obj_byte_array", object2Bytes(dataObj));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dataIntent.putExtras(dataBundle);
startActivity(dataIntent);
}
オブジェクトをバイト配列に変換する
/**
* Converting objects to byte arrays
*/
static public byte[] object2Bytes( Object o ) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream( baos );
oos.writeObject( o );
return baos.toByteArray();
}
バンドルからオブジェクトを取得します。
class SecondClass{
DataBean dataBean;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...
//Get Info from Bundle...
Bundle infoBundle=getIntent().getExtras();
try {
dataBean = (DataBean)bytes2Object(infoBundle.getByteArray("Obj_byte_array"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
バイト配列からオブジェクトを取得するメソッド:
/**
* Converting byte arrays to objects
*/
static public Object bytes2Object( byte raw[] )
throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream( raw );
ObjectInputStream ois = new ObjectInputStream( bais );
Object o = ois.readObject();
return o;
}
これが他の仲間に役立つことを願っています。
1.非常に直接的で使いやすい例として、渡されるオブジェクトをSerializableに実装します。
class Object implements Serializable{
String firstName;
String lastName;
}
2.オブジェクトをバンドルで渡す
Bundle bundle = new Bundle();
Object Object = new Object();
bundle.putSerializable("object", object);
3.バンドルから渡されたオブジェクトをSerializableとして取得し、オブジェクトにキャストします。
Object object = (Object) getArguments().getSerializable("object");
これは私自身の質問にはかなり遅れた答えですが、注目を集め続けているので、私はそれに対処する必要があると感じています。これらの答えのほとんどは正しく、仕事を完全に処理します。ただし、アプリケーションのニーズによって異なります。この回答は、この問題の2つの解決策を説明するために使用されます。
サービスは、長時間実行される操作を実行できるアプリケーションコンポーネントです。 背景とユーザーインターフェイスを提供しません。サービスは、制御が容易な、より明確なライフサイクルを持つという点で優れています。さらに、必要に応じて、サービスをアプリケーションの外部で(つまり、起動時に)実行できます。これは、一部のアプリまたは単なるきちんとした機能に必要な場合があります。
これも完全な説明ではありませんでしたが、さらに調査したい人のためにドキュメントへのリンクを残しました。全体としてService
は、必要なインスタンスの方が優れています。SPPデバイスに対してServerSocketを実行します。
Dateオブジェクトを渡す方法を探しているときに、この質問に遭遇しました。私の場合、回答の中で示唆されているように、Bundle.putSerializable()を使用しましたが、元の投稿で説明されているDataManagerのように複雑なものには機能しません。
上記のDataManagerをアプリケーションに配置するか、シングルトンにするのと非常によく似た結果が得られるという私の提案は、依存性注入を使用してDataManagerをシングルトンスコープにバインドし、必要な場所にDataManagerを注入することです。テスト容易性が向上するだけでなく、すべてのボイラープレート「クラスとアクティビティ間の依存関係を渡す」コードがなくても、よりクリーンなコードが得られます。(Robo)Guiceは非常に扱いやすく、新しいDaggerフレームワークも有望に見えます。