2015-01-22 3 views
2

Android 개발에 대해 배우기 시작했고 정적 변수에 대해 읽었습니다. 가비지 수집 가능하지 않기 때문에 메모리가 누수 될 수 있습니다.공용 정적 필드/변수를 사용하는 것이 좋지 않습니까?

특정 상황에서 일부를 사용했지만 메모리가 누출 될 우려가 있습니다.

누군가 내 코드를보고 메모리 누출 여부를 확인하십시오.

MainActivity.java

public class MainActivity extends Activity { 

public static boolean IS_ACTIVITY_OPEN; 
public static ImageView image; 

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main_layout);   
     IS_ACTIVITY_OPEN = true; 

    .... 

    .... 

    VoiceReceiver = new BroadcastReceiver() { 

    @Override 
    public void onReceive(final Context context, Intent intent) { 
     ..... 
    }; 
    registerReceiver(VoiceReceiver, new IntentFilter(BroadCastReceivers.VoiceIntent)); 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    unregisterReceiver(VoiceReceiver);   
    IS_ACTIVITY_OPEN = false; 
    } 
} 

Picture.java

MainActivity.image.setImageBitmap(resizedBitmap); 

.....

.....

BroadCast.java

if (!MainAcitivty.IS_ACTIVITY_OPEN) { 
    //start an activity 
    Intent intent2 = new Intent(context, MainAcitivty.class);    
    intent2.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); 
    context.startActivity(intent2); 
    handler= new Handler(); 
    MyPostDelay = new Runnable() { 

     @Override 
     public void run() { 
      context.sendBroadcast(new Intent(VoiceIntent)); 
     } 
    }; 
    handler.postDelayed(MyPostDelay, 300); 
} 
else 
{ 
    context.sendBroadcast(new Intent(VoiceleIntent)); 
} 

미리 감사드립니다.

+0

글쎄, 캐싱 뷰는 다시 만들어 지도록 설계되었으므로 뷰를 잘못 작성하면 오브젝트의 상태에 따라 true 또는 false를 반환하는 간단한 getter로 해당 public boolean을 대체 할 수 있기 때문에 뷰를 캐싱하는 것은 좋지 않습니다. 일반적으로 바뀌지 않을 값을 생성하기 위해 final과 결합 된 static을 사용하는 것은 괜찮습니다. "언제 어디서나 액세스 할 수 있어야합니까?"라는 질문에 대답 할 수 없다면 예, 공개 정적 변수와 메소드를 만들지 마십시오. –

+0

무서워하는 경우 데이터를 유지하고 통계 변수를 활동에 넣으면 수신자가 일종의 방식 (예 : 싱글 톤 또는 저렴한 sharedpreference)을 수행하고 이미지 뷰를 보유하는 것이 좋지 않습니다. 오히려 .. imageview.bildDrawingCache()와 같은 뭔가 it.goes google 수 있습니다. – Elltz

+0

귀하의 의견에 진심으로 감사드립니다. SharedPreferences를 사용하여 IS_ACTIVITY_OPEN 부울을 저장 한 다음 BroadCast에서 검색하면 좋을 것입니다. 맞습니까? SharedPreferences에서 IS_ACTIVITY_OPEN 부울을 검색 할 때 새 부울 값이 가비지 수집 가능합니까? 고마워요 –

답변

3

Android 개발자 블로그에서 Avoiding memory leaks 문서를 확인하십시오. static 필드가 컨텍스트를 유지하거나 컨텍스트 (예 : 임의의 뷰)에 대한 (강한) 참조를 갖는 다른 클래스를 유지하면 가비지 수집기가 컨텍스트에 의해 할당 된 저장소를 다시 사용할 수 없음을 의미합니다. 컨텍스트가 응용 프로그램 인 경우 응용 프로그램과 동일한 기간 동안 살아 있기 때문에 OK입니다. 어쨌든 가비지 수집되지 않습니다. 그러나 Views의 경우 Context는 가능한 한 빨리 가비지 수집해야하는 활동 일 가능성이 큽니다.

그렇다고 모두 정적 인 필드가 치명적인 메모리 누출을 의미하지는 않습니다. 기본 유형 또는 단순 클래스이거나 다른 클래스에 대한 약한 참조가있는 더 복잡한 클래스 인 경우 가비지 콜렉터가 많은 메모리를 회수하지 못할 수 있습니다. 하지만 일반적으로 의 정적 인 및 특히 의 public static 필드는 코드 냄새이므로 코드를 나중에 쉽게 유지할 수 있도록 피해야합니다.

+0

의견을 많이 주셔서 고마워 –

+0

제발 내가 도이 하나 도와주세요 제발 도와 줄래? 나는 활동 전반에 걸쳐 하나의 String 또는 int를 사용 해왔다. 예를 들어, 처음에는 private String imagePath를 초기화하고 다른 방법으로 사용합니다. 예를 들어, imagePath = "....."그리고 나서 다른 메소드에서 File file = new File (imagePath)을 호출합니다. 나는이 생각이 기억을 잃을 까봐 두렵다.기본적으로,이 imagePath 주위에 떠 다니는과 반복되고, 나쁘지 않아? –

관련 문제