現在、複雑なデータ構造をフラグメントまたはアクティビティに渡すために、http://developer.android.com/guide/faq/framework.html#3で説明されている戦略を使用しています
長いキーを持つオブジェクトへの WeakReferences の HashMap を使用することもできます。アクティビティがオブジェクトを別のアクティビティに渡したい場合、オブジェクトをマップに配置し、インテント エクストラを介して受信者アクティビティにキー (カウンターまたはタイム スタンプに基づく一意の Long) を送信するだけです。受信者アクティビティは、このキーを使用してオブジェクトを取得します。
私Application
はグローバルにアクセス可能な を保持するためにHashMap
使用し、次のコードを使用して Long キーを介して送信します。
public class MyFragment extends Fragment {
public static MyFragment newInstance(long myArrayId) {
// This is how I receive the object Id.
MyFragment myFragment = new MyFragment();
Bundle bundle = new Bundle();
bundle.putLong(MyApplication.INTENT_EXTRA_MY_ARRAY_ID, myArrayId);
myFragment.setArguments(bundle);
return myFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This is how I turn Id into Object.
this.myArrayIdId = this.getArguments().getLong(MyApplication.INTENT_EXTRA_MY_ARRAY_ID);
this.myArray = (MyArray)MyApplication.instance().getExtra(myArrayIdId );
私は最初、これはかなり良い戦略だと思いました。特に、 を使用して実装するのは不可能と思われる複雑なデータ構造の場合Parcelable
。
ほとんどの場合、この戦略はうまく機能します。ただし、動作しない状況があります。Application
しばらくアクティブにしないと、システムが を破壊する可能性があることがわかりました。
これは、問題を再現する方法です。
- アプリを実行する
- ホームを押す
- メモリを集中的に使用する他のアプリを実行し、[ホーム] を押して、他のアプリを再度実行します。
- ホームボタンを長押しします。アプリは引き続きリストに表示されます。
- それを選択します。
HashMap
オブジェクトが空であることがわかります。(nullオブジェクトを取得すると、アプリケーションがクラッシュします)
信頼できる解決策の 1 つは、オブジェクトを staticHashMap
に格納するのを避け、Bundle に as として配置することParcelable
です。
しかし、ファイル ハンドル、スレッド ハンドル、並行データ構造などを持っているため、クラスを として配置できない場合、Parcelable
これを克服するための戦略は何ですか?
私は、同様の質問がかなりの数提起されたことを知っています。しかし、良い解決策はないようです。(参照してください、Google 自身の FAQ でさえ、静的な HashMap への保存は常に機能するとは限りません)