通常、静的な使用は、通常、オブジェクト指向の設計が悪いことを示していますが、それ以上に注意してください。 スタティックのライフサイクルは、ライフサイクルと同じようにリソースはに作成されます。
はのは、一例として@BasimKhajwalの答えを見てみましょう:
class Assets { /*...*/
private static final AssetManager assetManager = new AssetManager();
このコードnew AssetManager()
が実際に実行されますか?これは、VMが初期化された後に実際に直接実行されます。したがって、アプリケーションウィンドウが実際に作成される前であっても、すべてのネイティブライブラリがロードされてOpenGLコンテキストが作成される前であってもかまいません。
public static void loadAll() { /* load things */ }
このコードはいつ実行されますか?これはおそらく、あなたのApplicationListenerのcreate
メソッドのどこかで呼び出します。したがって、のOpenGLコンテキストでは、アプリケーションの特定のインスタンスが作成され、その時点でアクティブになり、そのアプリケーションのレンダースレッドで呼び出されます。
は今のAndroid上で動作して、次のような状況を考慮してください。
あなたのVM静的な資産は、そのアプリケーションのコンテキストにロードされ、あなたはそのコンテキストでそれらを使用することができます。その後、電話がかかり、アプリケーションがバックグラウンドでプッシュされます。しばらくすると、Androidはメモリを解放する必要があると判断し、OpenGLのコンテキストなどを含むアプリケーションを閉じます。
電話が終了したら、ゲームに戻ります。 Androidはあなたのゲームの新しいインスタンスを開始します。そのため、同じAssetManagerと既にロードしているすべてのアセットを含む、アプリケーションの前のインスタンスの同じVMを再利用します。アプリケーションは新しいOpenGLコンテキストなどを作成しますが、アセットは以前の無効なコンテキストを指しています。したがって、資産を無効にし、望ましくない行動を引き起こします。
もちろん、通常のテストではこのような問題は見つけられません。 Androidがアプリケーションを閉じてVMをリサイクルするかどうかは保証されません。しかし、いくつか試してみると、上記のステップを再現できるはずですので、リソースがどのように無効になっているかを自分で確認できます(たとえば、テクスチャが黒くなるなど)。 saidの場合でも、アプリケーションの複数のインスタンスを同じVMで実行することができます(Playストアと起動画面から起動する場合など)。
この問題を回避することができます。例えば、libGDXはアプリケーションの各インスタンスに対してすべてのリソースのMap
を保持することで内部的にそれを行います(どのように動作しているかは、hereの例です)。しかし、最初にObject Oriented Designを適切に実装していない可能性が高いので、あなたのアプローチを再考する方がよいでしょう。
static
をまだ使用する場合は、ライフサイクルを完全に理解してください(アプリケーションの特定のインスタンスよりも寿命が長い、またはそれに限定されているとは限りません)。
これは恐らく最も大きな間違いの1つであることに注意してください(「仮想」ピクセルの隣に)。ちょっと検索すると、特にAndroidで静的な問題がある人の例がかなり見つかります。ただし、Androidで最も多く出展していますが、デザイン上の問題です。 Androidをターゲットにしていないときにあなたに当てはまるわけではありません。静的リソース(または重要な静的変数)がまったく必要ないように、アプリケーションを設計することは完全に可能です。
これは、静的クラスを誤って使用することに比べて、静的クラスを使用することの一般的な落とし方が少なくなります。一貫したアプリケーション全体のスタイルでは、これは適切なようです。 – Compass