26

いくつかの静的変数を持つアプリケーションがあります。これらの変数は、DataContext という名前の独立したクラスに格納されます。これらの変数は、アプリケーションの開始時に raw ファイルから初期化されます (アプリケーションを拡張する MyApplication の onCreate() で DataContext.initConstant() という名前のメソッドが呼び出されます)。

(編集: initConstant メソッドは、AsyncTask を使用してこのデータをファイルからロードします)。

アプリケーションが一定時間バックグラウンドになったとき、またはアプリケーションが大量のメモリを使用したときに、これらの静的変数が null になります。

  1. どうすれば防ぐことができますか?

  2. そうでない場合、静的変数をどうすればよいですか?

    さまざまなアクティビティで使用するために静的変数に格納されている他のデータがありますが、それらをクリアするかonLowMemory()、MyApplication で null に渡します。

  3. これらのデータが大きすぎてインテントでシリアライズできず、(何らかの理由で) データベースを使用できず、シリアライゼーションによってファイルに保存できない場合、アクティビティ間で一部のデータにアクセスできるようにする最善の方法は何ですか?

4

7 に答える 7

5
  1. できません。Androidは時々メモリを解放する必要があります。すべてのアプリケーションに、永久に存在するはずの大量の静的データがあると想像してみてください。それをメモリにどのように収めますか?携帯電話です。仮想メモリはありません。

  2. (および3):永続的であることが意図されているものはすべて、SharedPreferences、Sqliteデータベース、またはファイルのいずれかを介して保存する必要があります。

于 2011-01-25T18:10:51.113 に答える
5

おそらく問題は、アプリケーションがバックグラウンドにある間に強制終了され、戻ってきたときに再作成されることです。単一のアクティビティでこれがいつ発生するかについては、 Activity Lifecycleのドキュメントを確認してください。アプリが強制終了された場合にその情報が失われないように、メモリに保存されているものはすべて、正しい時点でより永続的なストレージに移動する必要があります。

何を保存しているのか正確にはわかりませんが、共有設定を使用するとうまくいくようです。データ ストレージに関するこのページでは、共有設定など、データをより永続的に保存するさまざまな方法について説明します。

于 2011-01-25T18:13:02.457 に答える
2

これはデータキャッシュの問題だと思います。

ユーザーがアプリを頻繁に交換する場合、静的クラスへのデータの格納は保証されません。メモリが少なくなると、Android システムはバックグラウンド アクティビティを再利用します。静的クラスは間違いなくこのカテゴリに含まれます。

これを行う適切な方法は、sharedPreferenceを使用してキャッシュ データを永続化することです。

必要なデータの独自のゲッターとセッターを作成し、それを sharedPreference オブジェクトにラップできます。getter を使用してアクセスする場合は、値が空であるか有効期限が切れていないかを常に確認する必要があります。update_timeセッター使用時に格納できます。

アクティビティ固有のデータについては、 を使用できます。getPreference(permission)アクティビティや他のアプリケーション コンポーネント間でデータを共有する場合は、 を使用できますgetSharedPreference(name, permission)

通常、パーミッションは MODE_PRIVATE で、アプリケーション内でのみデータにアクセスできます。

データをグループ化し、別の sharedPreference オブジェクトに格納する必要があります。そのデータのグループを無効にしたい場合、それは 1 つのライナーの問題であるため、これは良い方法です。

editor.clear(); editor.commit()

複雑なオブジェクトをキャッシュしたい場合は、シリアル化する必要があります。私は JSON 形式を好みます。したがって、何らかの変換メカニズムが必要です。これを行うには、JSONable クラスを拡張するデータ オブジェクト クラスを作成します。JSONable クラスにはtoJSON()メソッドとreadFromJSON(). これは、データを復元してシリアライズする場合に便利です。

于 2013-03-27T11:58:03.847 に答える
2

生ファイルを使用していない場合は、クラスのロード時に初期化することをお勧めします。

例えば、

public static Map<?,?> myStaticMap = new HashMap<?,?>();
static { //fill myStaticMap }

そのようにファイルをロードしている場合、心配するべき大きな懸念事項がいくつかあります。たとえば、I/O エラーや遅延の問題はどうでしょうか? メインスレッドで I/O を実行すると、gingerbread で警告が表示されます (有効にしている場合)。おそらく、静的フィールドを持つクラスではなく、これらの値を取得するためのオブジェクトが必要です。(おそらく静的キャッシュを使用しますが、チェック/変更する前に同期する必要があります)

于 2011-01-25T18:29:06.740 に答える
1

UserオブジェクトとClientオブジェクトを静的スコープに格納します。私は時々参照がnullになることに気づきました。そのため、ゲッターでこの値がnullかどうかを確認し、nullの場合はアプリを再起動します。

Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                context.startActivity(i);

アクセストークンを設定に保存しているため、クライアントをリロードすることもできますが、初期化が多すぎるため、アプリを再起動するのが最善の方法であると判断しました。

于 2011-01-25T18:19:02.207 に答える
1

onResume()メソッドでは、静的データにクエリを実行して、存在するかどうかを確認し、存在しない場合は再度ロードすることができます。

于 2012-08-28T13:15:14.453 に答える
0

静的変数を使用する代わりに、共有設定を使用して値を格納できます。

注: 共有設定の場合も、重い負荷を与えるべきではありません。

共有設定変数を保存および取得するためのゲッターおよびセッター関数を備えたスーパークラスを用意することで、この問題を解決しました。

アプリケーションのすべてのクラスが、アクティビティではなくスーパー クラスを拡張しました。

于 2012-01-19T05:38:56.413 に答える