[解決済み】インテントでenumやオブジェクトを渡す(最適な解決方法)。
質問
開始時に2つの異なるArrayListにアクセスする必要があるアクティビティがあります。 両方のリストは、私自身が作成した異なるオブジェクトです。
基本的に、私はIntentからアクティビティにこれらのオブジェクトを渡す方法が必要です。 私はaddExtras()を使用することができますが、これはParceableと互換性のあるクラスを必要とします。 私はシリアライザブルに渡されるように私のクラスを作ることができましたが、私が理解するように、これはプログラムを遅くします。
どのような選択肢がありますか?
Enumを渡すことはできますか?
余談ですが、インテントからアクティビティ コンストラクタにパラメータを渡す方法はありますか?
どのように解決するのですか?
これは古い質問ですが、誰もがEnumsが実際には
Serializable
そのため、Intentに追加することができます。このように。
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
静的変数やアプリケーション全体の変数を使うという提案は、本当に悪い考えです。これは本当にあなたの活動を状態管理システムに結合してしまい、メンテナンス、デバッグ、問題解決を困難にします。
ALTERNATIVES
良い点を指摘されたのは テジーク が提供するソリューションが オーデリック がエラーになります。しかし、提示された代替案は、(ジェネリックを使っても)ちょっと使いづらいです。
もし、Intentにenumを追加する際のパフォーマンスについて本当に心配しているのであれば、代わりに以下の代替案を提案します。
オプション1:
public enum AwesomeEnum {
SOMETHING, OTHER;
private static final String name = AwesomeEnum.class.getName();
public void attachTo(Intent intent) {
intent.putExtra(name, ordinal());
}
public static AwesomeEnum detachFrom(Intent intent) {
if(!intent.hasExtra(name)) throw new IllegalStateException();
return values()[intent.getIntExtra(name, -1)];
}
}
使用方法
// Sender usage
AwesomeEnum.SOMETHING.attachTo(intent);
// Receiver usage
AwesomeEnum result = AwesomeEnum.detachFrom(intent);
OPTION 2: (汎用的、再利用可能、enumから切り離された)
public final class EnumUtil {
public static class Serializer<T extends Enum<T>> extends Deserializer<T> {
private T victim;
@SuppressWarnings("unchecked")
public Serializer(T victim) {
super((Class<T>) victim.getClass());
this.victim = victim;
}
public void to(Intent intent) {
intent.putExtra(name, victim.ordinal());
}
}
public static class Deserializer<T extends Enum<T>> {
protected Class<T> victimType;
protected String name;
public Deserializer(Class<T> victimType) {
this.victimType = victimType;
this.name = victimType.getName();
}
public T from(Intent intent) {
if (!intent.hasExtra(name)) throw new IllegalStateException();
return victimType.getEnumConstants()[intent.getIntExtra(name, -1)];
}
}
public static <T extends Enum<T>> Deserializer<T> deserialize(Class<T> victim) {
return new Deserializer<T>(victim);
}
public static <T extends Enum<T>> Serializer<T> serialize(T victim) {
return new Serializer<T>(victim);
}
}
使用方法
// Sender usage
EnumUtil.serialize(AwesomeEnum.Something).to(intent);
// Receiver usage
AwesomeEnum result =
EnumUtil.deserialize(AwesomeEnum.class).from(intent);
OPTION 3 (Kotlinを使用)。
少し時間が経ってしまいましたが、Kotlinが登場したので、新しいパラダイムに対応した別のオプションを追加しておこうと思います。ここでは、拡張関数とreified型(コンパイル時に型が保持される)を利用することができる。
inline fun <reified T : Enum<T>> Intent.putExtra(victim: T): Intent =
putExtra(T::class.java.name, victim.ordinal)
inline fun <reified T: Enum<T>> Intent.getEnumExtra(): T? =
getIntExtra(T::class.java.name, -1)
.takeUnless { it == -1 }
?.let { T::class.java.enumConstants[it] }
このようにすると、いくつかの利点があります。
-
のおかげで、シリアライズを行うための中間オブジェクトのオーバーヘッドを必要としない。
inline
で、その呼び出しを関数内のコードに置き換えます。 - 関数はSDKのものと似ているため、より親しみやすいと思います。
- IDEがこれらの関数をオートコンプリートするので、ユーティリティクラスに関する予備知識は必要ありません。
デメリットとしては、Emumsの順番を変えると、古い参照は使えなくなることです。これは、保留中のIntentの内部で、更新に耐えられない可能性があるため、問題になることがあります。しかし、それ以外の場合は、問題ないでしょう。
注意すべきは、位置の代わりに名前を使うような他の解決策も、いずれかの値の名前を変更すると失敗することです。ただし、そのような場合は、不正なEnum値の代わりに例外が発生します。
使用方法
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()
関連
-
[解決済み】Android Studioでパラメータ化されたユニットテストを実行すると、指定されたインクルードに対するテストが見つからないエラーが発生する
-
[解決済み] ユーザーが拒否する可能性のあるパーミッションが必要なコール
-
[解決済み】このアクティビティは、すでにウィンドウ装飾によって提供されるアクションバーを持っています。
-
[解決済み】起動アクティビティを特定できませんでした。デフォルトのアクティビティが見つかりませんでした
-
[解決済み】'dependencies' を '(groovy.lang.Closure)' に適用できない。)
-
[解決済み】アクティビティにない場所でのgetLayoutInflater()の呼び出し
-
[解決済み] Android Studioで「URIが登録されていません」と報告されるのはなぜですか?[クローズド]
-
[解決済み] SDKの場所がandroid studioで見つからない
-
[解決済み] AndroidでEditTextのテキスト長を制限する最も良い方法は何ですか?
-
[解決済み] AndroidでSQLiteを使用する際に、並行処理の問題を回避するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Android TextView : "setTextで表示されたテキストを連結しない" について
-
[解決済み】まだ警告が出る:設定 'compile' は時代遅れで 'implementation' に置き換わった。
-
[解決済み】「ArrayAdapterはリソースIDがTextViewであることが必要」XMLの問題点
-
[解決済み】インストールエラー。インストールエラー:install_failed_older_sdk
-
[解決済み】Android Studioの初回起動。Android SDKアドオンリストにアクセスできない
-
[解決済み】レンダリングの問題 レンダリング中に発生した例外:com/android/util/PropertiesMap [重複].
-
[解決済み】sendUserActionEvent()がnullである。
-
[解決済み】アクティビティにない場所でのgetLayoutInflater()の呼び出し
-
[解決済み] sendUserActionEvent() は null です。
-
[解決済み] android.support.design.widget.FloatingActionButton クラスの展開に失敗しました。