2016-09-30 2 views
0
public class MyClass { 
    private static MyClass instance = null; 
    private MyActivity myActivity; 
    private Button button; 

    public static MyClass getInstance(){ 
     if (instance == null){ 
      instance = new MyClass(); 
     } 
     return instance; 
    } 

    private MyClass(){}; 

    public void initialize(MyActivity activity){ 
     myActivity = activity; 
    } 

    public void releaseMemory(){ 
     instance = null; 
    } 
} 

そして 私はそのmyActivity インスタンスが漏洩することはありません)releaseMemoryを(呼び出すことによって、メモリを解放することができます。このアプローチではメモリ割り当ての違い

public class MyClass { 
    private static final MyClass instance = new MyClass(); 
    private MyActivity myActivity; 
    private Button button; 


    private MyClass(){}; 

    public void initialize(MyActivity activity){ 
     myActivity = activity; 
    } 

    public void releaseMemory(){ 
     instance = null; //Can't make it null 
     //Can do for individual variables 
     myActivity = null; 
     button = null; 
    } 
} 

MyClassのインスタンスは、私はそれが ヌル代わりに私がnullとして個々の変数を作ることができることはできません最終的なものとして。

私の理解が正しいですか、またはメモリリークに関連するものが何もありませんか?

+1

Javaには、メモリ管理を行うガベージコレクタがあります。明示的に 'null'への参照を割り当てる必要はありません。 –

+0

@MickMnemonicこれらは静的インスタンスなので、クラスがアンロードされたときにのみガベージコレクションされます。Androidでアクティビティ変数をnullにしなかった場合、メモリリークを報告します。 – sankar

+0

実行時に解放されずに何度も何度も割り当てられた場合、「メモリリーク」が発生します。あなたの場合、MyClassクラスは、JVMの実行が終了するまでインスタンス化されたままです。 – Heri

答えて

0

最初の質問は、なぜActivityオブジェクトの参照を保持する必要がありますか?

ほとんどの場合、Contextオブジェクトが必要です。だから、あなたはあなたのActivity置き換えることにより、以下のことを行うために習慣を取る漏洩しないようにしたい場合:

private MyActivity myActivity; 

public void initialize(MyActivity activity){ 
    myAcitivity = activity; 
} 

で:

private Context myContext; 

public void initialize(Context context){ 
    myContext = context.getApplicationContext(); 
} 

活動はコンテキストの実装ですので、あなたのコードが動作し続ける必要があります。メソッドgetApplicationContext()は、常にアプリケーションコンテキストを返します。アプリケーションコンテキストは、必要なすべてを漏らすことができます。

アプリケーションコンテキストが十分でなく、実際にアクティビティオブジェクトが必要な場合(例として新しいタスクを作成せずに他のアクティビティを開始する必要がある場合)は、まず自分のアクティビティクラス直接。できない場合は、おそらくコードアーキテクチャに関して悪い決断をしたことがあります。

あなたが本当に他のオブジェクト(シングルトンまたはしない)でActivityオブジェクトを格納する必要がある場合は、活動がライフサイクルを持っている、とあなたはドン場合、それは」(利用できなくなりますあなたのMyClassに通知するために、あなたのActivityが必要であることを忘れないでくださいトン、そしてあなたはそれがバックグラウンドに行くときに、あなたのActivityが漏れますreleaseMemoryを()、呼び出すことを忘れ):ここで

public class MyActivity { 

    MyClass myClass; // instance initialize somewhere in your code 

    onPause() { 
     myClass.setActivity(this); 
    } 

    onResume() { 
     myClass.setActivity(null); 
    } 
} 

public class MyClass { 

    @Nullable Activity myActivity; // tha @Nullable annotation helps you remember to do null checks before using this field. 

    public void setActivity(Activity activity) { 
     myActivity = activity; 
    } 
} 

あなたMyClassFragmentで、あなたのActivityを設定し、リリースの仕事をすることができますonAttach()およびonDetach()のメソッド(これらのメソッドは自動的にcあなたはActivityでそれらを呼び出すことを試みる必要がないので、Androidによってalled)。あなたのメソッドreleaseMemory()を呼び出して、あなたのオブジェクトAに残された参照を持っていないことを確認しても、あなたはBはまだないオブジェクトを確実にするためにできることは何もないので

最後に、私は、あなたの最初のコードサンプルに対して助言しますあなたのクラスMyClassへの参照があります。

0

最終フィールドは変更できません。そのため、最終修飾語が存在します。

あなたのシングルトンの2番目のバージョンがconccurencyに関してより優れています。あなたがアプリを閉じるまでそれは決してgc'edされません。