2011-12-30 6 views
5

数日前、私はシングルトンがAndroidでアンチパターンになる可能性があることを発見しました。私のシングルトン(プライベートコンストラクタを持つクラスと静的フィールドに格納されているインスタンス)は削除されました(別のインスタンスが作成されなければならないため、他のアクティビティがこのシングルトンを(getInstance()メソッドを使用して)最初に呼び出されたものが削除されました(この1つのアクティビティーのみを終了した後)。Androidでのenumベースのシングルトンのライフサイクル

私は既にこの問題を解決する方法を読みましたが、「効果的なJava」も読んでいます。 「単一要素列挙型は、シングルトンを実装するためのバストウェイです」と言われています。

これで、Androidアプリケーションでこのように作成されたシングルトンのライフサイクルはどうなっているのでしょうか? 「標準的なシングルトン実装」の場合と同じように、それが最初に呼び出されたアクティビティを破棄した後で(たとえそれが他のアクティビティでも使用されたとしても)破棄されるでしょうか?

私は適切なアンドロイドシングルトンの実装やシングルトンパターン自体については問いませんが(パターンやアンチパターンなど)、そのようなenumシングルトンオブジェクトのライフサイクルは何か破壊されました。

+0

シングルトンは、一般に反パターンです。何かが本当に必要な場合は、別のものを作成しないでください:P – cHao

+0

これは、いくつかの説明を必要とする可能性があります。シングルトンエニュウムに入れてください)、あなたのアクティビティが終了したときにアンドロイドから参照されて消えました(そしてあなたのアプリケーションもシャットダウンされました)?これはシングルトンの期待される動作でしょう - アプリケーションの再起動の間に保持する必要があるすべての状態 - OTOH、私は完全に質問を誤解している可能性があります: - D – Jens

+0

@Jens私は私の質問を更新しました。 – mmatloka

答えて

2

使用するクラスはすべて、ロードされたClassLoaderに関連付けられています。これはAndroidだけでなく一般的にJavaにも当てはまります。 Androidは毎回新しいClassLoaderを使用してアクティビティを隔離します。少なくとも、それはそうでないとは約束しません。

シングルトンまたは他のクラスレベルの状態は、ClassLoaderに関連付けられたClassに関連付けられています。これがあなたの国が「消える」理由です。実際には、あなたの呼び出しコードは新しいClassLoaderの新しいClassを見ています。

このように、列挙型のトリックやこれらの行に沿ったものは、まったく同じ動作をします。あなたはちょうどこのように活動情報を「持続」することはできません。 SQLite DBに書き込むことができます。あなたはおそらくSharedPreferencesにそれを隠すことができます。

-2

マイ安全なシングルトンの実装では、そのようなものです:

私はブール「didReceiveMemoryWarning」の属性を持つシングルトンクラスを作成します。アプリケーション最初の画面(それはまさに最初の起動画面です)(私は目に見える3秒でスプラッシュスクリーンを持っている)

SingleTon.getInstance().didReceiveMemoryWarning = false; 

、すべての活動ののonCreate()メソッド内で

public class SingleTon(){ 
    public boolean didReceiveMemoryWarning = true; 
    ... 
    ... 
} 

、このブール値をチェックしますデータ、

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if(SingleTon.getInstance().didReceiveMemoryWarning){ 
      { Load your data from local to your SingleTon class, 
      because your app was released by OS}; 
    } 
} 

私の実装です。

+0

これは単なるシングルトンです。彼はこれがうまくいかないと言っています。 –

0

アプリケーションオブジェクトは、さまざまなアクティビティやサービスインスタンスからアクセス可能な情報を格納するのに適しています。このように(アクティビティまたはサービスの場合)、次のように取得できます。

private MyApplication app;

in onCreate(...){ ... this.app =(MyApplication)this.getApplication(); ... }

マニフェストにも名を設定することを忘れないでください:値は、あなたのアプリのパッケージへの相対クラスへのパスです : は、「アプリケーション」タグの属性「名前」に設定します。

アプリケーションが起動されたときにアプリケーションオブジェクトが作成され、onCreate()メソッドでアクティビティやサービスのように初期化できます。

覚えておくべきこと:アプリケーションオブジェクトは、「最後の」アクティビティを閉じても生き残ることができます。この場合、アプリケーションとの前回の対話からの状態で、同じアプリケーションオブジェクトを取得することができます。これが問題の場合は、アプリケーションの初期起動を何とか検出する必要があります(UIを持たない特別なランチャーアクティビティを使用してアプリケーションオブジェクトを初期化し、新しいインテントを開始するなど)。 シングルトンでは、

関連する問題