50

Androidで静的変数を使用することは、特にアクティビティを参照する場合、非常に危険であることを私は知っています。ただし、Applicationを拡張するクラス(このクラスを「App」と呼びましょう)がある場合、このクラスのインスタンスを参照しても安全ですか?

もしそうなら、他のクラスがアプリケーションコンテキストへの何らかの参照を持つことも安全ですか?つまり、任意の種類のクラスのアプリケーションコンテキストへの参照がある場合、メモリリークが発生する可能性がありますか?

目的は、どのスコープにいても、常にアプリケーションコンテキストへの参照を取得できるようにすることです。システムがアプリケーションを閉じると、次にアプリケーションが再起動するまで静的変数も失われ、静的変数が再び初期化されるため、安全だと思います。

また、それはそれほど重要ではありませんが、複数のプロセスを使用する場合、各プロセスでAppクラスへのまったく異なる参照を取得しますか?

コードの例として、私が考えていることは次のとおりです。

public class App extends Application
{
    private static Context _appContext;

    @Override
    public void onCreate()
    {
        super.onCreate();
        _appContext = this;
    }

    public static Context getAppContext()
    {
        return _appContext;
    }
}
4

5 に答える 5

31

アプリのコンテキストを静的変数に保存しても安全ですか?

現在、はい、それは安全であるように見えますgetAppContext()が、私はreturnを持っていませんがContext、代わりにreturnAppまたはApplication

そうは言っても、Androidのコアチームがそもそもこのように設定しなかったという事実は、おそらく私たちが気付いていない隠れた問題があるかもしれない、または将来このアプローチが問題を引き起こすかもしれないことを示唆しています。

ことわざの頭字語が行くように、YMMV。:-)


編集

もしそうなら、他のクラスがアプリケーションコンテキストへの何らかの参照を持つことも安全ですか?

ここで「安全」とはどういう意味かわかりません。

しかし、複数のプロセスを使用する場合、各プロセスでAppクラスへのまったく異なる参照を取得しますよね?

複数のプロセスを使用する場合は、マスで叩く必要があります。ただし、はい、Appプロセスごとに個別のインスタンスを取得する必要があります。

于 2012-04-21T11:48:31.333 に答える
9

安全なはずです。また、 APIドキュメントからの次のメモがあなたに関連している可能性があります。

通常、サブクラス化する必要はありませんApplication。ほとんどの場合、静的シングルトンは、よりモジュール化された方法で同じ機能を提供できます。シングルトンにグローバルコンテキストが必要な場合(たとえば、ブロードキャストレシーバーを登録するため)、それを取得する関数にContext.getApplicationContext()、最初にシングルトンを作成するときに内部的に使用するコンテキストを指定できます。

于 2012-07-20T09:31:34.660 に答える
5

はアクティビティの前に作成されるApplication#onCreate()ため、これを行うのは安全です。Applicationアプリがバックグラウンドで強制終了された場合、Applicationアクティビティが実行される前にインスタンスが再作成され、グローバルが設定されます。

アクティビティからグローバル変数を設定してはならないことに注意することが重要です。その場合、アプリは次のように失敗する可能性があります。

  1. アクティビティAでグローバルに設定
  2. アクティビティBに移動します
  3. アプリがバックグラウンドに入る
  4. フレームワークはアプリとプロセスを殺します
  5. アプリが復元されます
  6. フレームワークはアクティビティBを作成 します。バックスタック内のアクティビティは、それらに戻るまで作成されないため、グローバルは設定されません。
  7. アクティビティBはグローバルを使用しようとし、ブーム...NullPointerException
于 2016-11-26T08:31:14.973 に答える
1

厄介な静的コンテキストを整理しているときに、Studioから興味深いコメントがポップアップしました。

「これはリークです(また、インスタントランを中断します)。」

そのため、Instant Runのリリースにより、Android開発者が静的変数の保存を計画していない場合があります。インスタント実行は(まだ)私の議題ではありませんが、それが悪い習慣であるだけでなく、それが間違っているユースケースが特定されている特定の例があることを知っておくと便利です。

于 2017-01-26T10:20:52.460 に答える
-1

Context context;これは、 android-studioでを作成するときの警告です。

Androidコンテキストクラスを静的フィールドに配置しないでください。これはメモリリークであり、インスタント実行も中断します。

静的フィールドはコンテキストをリークします。

非静的内部クラスには、外部クラスへの暗黙の参照があります。

その外部クラスがたとえばフラグメントまたはアクティビティである場合、この参照は、長時間実行されるハンドラー/ローダー/タスクが、ガベージコレクションを防ぐアクティビティへの参照を保持することを意味します。同様に、これらの長時間実行されているインスタンスからのアクティビティとフラグメントへの直接フ​​ィールド参照は、リークを引き起こす可能性があります。

ViewModelクラスは、ビューまたは非アプリケーションコンテキストを指してはなりません。

于 2018-10-23T15:21:03.877 に答える