121

バンドルを介して処理の大部分を行うクラスへの参照を渡す必要があります。

問題は、インテントやコンテキストとは何の関係もなく、大量の非プリミティブ オブジェクトがあることです。クラスをパーセル可能/シリアライズ可能にパッケージ化してに渡すにはどうすればよいstartActivityForResultですか?

4

11 に答える 11

160

また、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);
于 2013-02-01T12:09:02.707 に答える
56

どの道を進むべきかを理解するには、CommonsWare の主要な質問である「なぜ」だけでなく、「何に」という質問にも答える必要があります。あなたはそれを渡していますか。

現実には、バンドルを通過できるのは単純なデータだけです。それ以外はすべて、そのデータが意味するものや指し示すものの解釈に基づいています。文字通りオブジェクトを渡すことはできませんが、できることは次の 3 つのいずれかです。

1)オブジェクトを構成データに分解できます。反対側にあるものが同じ種類のオブジェクトの知識を持っている場合、シリアル化されたデータからクローンを組み立てることができます。これが、ほとんどの一般的な型がバンドルを通過する方法です。

2) 不透明なハンドルを渡すことができます。同じコンテキスト内でそれを渡す場合 (理由を尋ねる人もいるかもしれませんが)、それは呼び出しまたは逆参照できるハンドルになります。しかし、Binder を介して別のコンテキストに渡すと、そのリテラル値は任意の数値になります (実際、これらの任意の数値は起動時から順番にカウントされます)。元のコンテキストに戻すまでは何もできませんが、それを追跡することはできません。これにより、Binder はそれを元のハンドルに変換し、再び有用にします。

3) ファイル記述子や特定の os/platform オブジェクトへの参照などのマジック ハンドルを渡すことができます。適切なフラグを設定すると、Binder は受信者に対して同じリソースを指すクローンを作成します。これは実際に使用できます。もう一方の端。しかし、これはごく少数のタイプのオブジェクトでしか機能しません。

ほとんどの場合、相手がそれを追跡して後で返すことができるようにクラスを渡しているか、シリアル化された構成データからクローンを作成できるコンテキストにクラスを渡しています...またはそうでなければうまくいかないことをしようとしていて、アプローチ全体を再考する必要があります。

于 2010-11-23T05:32:16.050 に答える
22

Parcelableインターフェースは、Intent を持つオブジェクトを渡すのに適した方法です 。

カスタム オブジェクトを Parcelable にするにはどうすればよいですか? Parcelableの使用方法に関するかなり良い答えです

公式のGoogleドキュメントにも例が含まれています

于 2010-11-22T21:47:43.730 に答える
14

グローバルアプリケーション状態を使用できます。

アップデート:

これをカスタマイズして、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; 

お役に立てば幸いです。

于 2010-11-22T20:33:45.983 に答える
13

オブジェクトをシリアライズ可能にして、バンドルのgetSerializableおよびputSerializableメソッドを使用することもできます。

于 2010-11-22T22:29:48.377 に答える
7

バンドルを介してオブジェクトを送信するもう 1 つの方法は、bundle.putByteArray
サンプル コードを使用することです。

public class DataBean implements Serializable {
private Date currentTime;

public setDate() {
    currentTime = Calendar.getInstance().getTime();
 }

public Date getCurrentTime() {
    return currentTime;
 }
}

DataBean の Object を Bundle に入れる:

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;
    }

これが他の仲間に役立つことを願っています。

于 2012-12-11T11:18:28.413 に答える
0

バンドルを使用してオブジェクトを渡す別の簡単な方法:

  • クラスオブジェクトで、キーを持つ静的リストまたは別のデータ構造を作成します
  • オブジェクトを作成するときは、キーを使用してリスト/データ構造に入れます(つまり、オブジェクトが作成されたときの長いタイムスタンプ)
  • メソッド static getObject(long key) を作成して、リストからオブジェクトを取得します
  • バンドルでキーを渡すと、後でコードの別のポイントからオブジェクトを取得できます
于 2015-12-24T09:46:00.620 に答える
0

これは私自身の質問に対する非常に遅れた回答ですが、注目を集め続けているので、私はそれに対処しなければならないと感じています. これらの答えのほとんどは正しく、仕事を完璧に処理します。ただし、アプリケーションのニーズによって異なります。この回答は、この問題に対する 2 つの解決策を説明するために使用されます。

応用

ここで最も話題になっているのは Applicationです。アプリケーションは、Context への参照が必要なエンティティを配置するのに適したオブジェクトです。`ServerSocket` には間違いなくコンテキストが必要です (ファイル I/O または単純な `ListAdapter` 更新用)。個人的には、このルートが一番好きです。私はアプリケーションが好きです。それらはコンテキストの取得に役立ち (静的にすることができ、メモリリークを引き起こす可能性が低いため)、ライフサイクルが単純です。

サービス

Service`は 2 番目です「サービス」は、実際にはサービスが行うように設計されているため、私の問題にはより良い選択です:
サービスは、長時間実行される操作を実行できるアプリケーション コンポーネントです。
バックグラウンドであり、ユーザー インターフェイスは提供しません。
サービスは、制御しやすい、より定義されたライフサイクルを持っているという点で優れています。さらに、必要に応じて、サービスをアプリケーションの外部で (つまり、起動時に) 実行できます。これは、一部のアプリまたは単なる優れた機能で必要になる場合があります。

これはどちらも完全な説明ではありませんでしたが、さらに調査したい人のためにドキュメントへのリンクを残しました. 全体として、Service必要なインスタンスには優れています-SPPデバイスに対してServerSocketを実行しています。

于 2012-09-07T16:22:38.030 に答える