잘 알려진 소스 AsyncTasks
는 액티비티에 대한 참조를 보유되어, 예를 들면, 내부 클래스로서 태스크를 선언 할 때 :활동 내의 내부 클래스를 수용 할 수 없습니까? 메모리 누수
public class MyActivity extends Activity {
...
private class MyTask extends AsyncTask<Void, Void, Void> {
...
}
}
때문에 연관된 배경 스레드 (또는 스레드 풀)가, 쓰레드가 실행되고있는 한, 활동에 대한 참조는 활동이 닫히더라도 유지됩니다.
이제 내가 틀렸을 때 나를 고쳐주세요. 작업이 완료되면 활동을 다시 수집 할 수 있습니다.
- 보다 Runnable는 내부 클래스로 정의하고, 핸들러에 의해 메인 스레드에 게시 :
나는 거기에 활동을했습니다.
- TimerTasks는 내부 클래스로 정의됩니다.
나는 메모리 누수 그냥 타이머를 취소하고 핸들러에 removeCallbacks
를 호출 방지 수 있을까요?
예 :
public class MyActivity extends Activity {
Handler handler;
Timer timer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler();
timer = new Timer();
handler.postDelayed(new MyRunnable(), 10000);
timer.schedule(new MyTimerTask(), 1000);
}
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);
timer.cancel();
handler = timer = null;
}
private class MyTimerTask extends TimerTask {
...
}
private class MyRunnable implements Runnable {
...
}
}
나는 현재에서 일하고 있어요 프로젝트에서 이러한 활동을 보았다, 나는이 내부 클래스는 정적하고 활동에있는 WeakReferences를 추가 할 리팩토링 고려 중이 야 .
문제는 내부 클래스가 액티비티의 private 변수와 메서드에 대한 액세스 권한을 갖고 있으며 정적 변수로 변경하면 액티비티 클래스에있는 멤버의 액세스 한정자를 private에서 package-default로 변경해야하기 때문에 내부 클래스가 편리하다는 것입니다. 동일한 패키지의 다른 클래스에서 사용할 수 있도록합니다. 이것은 또한 액티비티 내에 package-default 인 메소드가 있고 그 대칭 함수가 여전히 private이기 때문에 대칭을 깨뜨린다. (예를 들어, 지금은 정적 클래스에서 액티비티의 stopFoo
메소드를 사용할 수 있어야한다. startFoo
으로 무엇을해야합니까? 그 클래스에서 호출되지 않았습니까?). 그리고 액티비티에서 액세스해야하는 변수는 무엇입니까? 지금 게터를 제공해야합니까?
약한 참조를 액티비티에 추가하면 리팩토링 된 정적 클래스에서 많은 수의 null 검사가 수행되므로 액티비티가 여전히 주변에있는 경우에만 작동합니다. 이 외에도 약한 참조 방법은 회사의 숙련되지 않은 프로그래머가 이해하기 어려울 수 있습니다. (또한 실제로 필요하지 않으면 어디서나 사용하기 시작할 수 있습니다.)
요약하면 리팩터링 된 활동은보기 흉한 반면 이전 사례는 깔끔합니다. 그래서 내부 클래스 기반 설계가 수용 가능한지, 활동이 끝났을 때 runnable 또는 timer 태스크가 잠깐 동안 실행되도록 남겨 두어도 상관하지 않는다는 사실을 알고 있는지 궁금합니다. 이제
정적이 아닌 내부 클래스를 피하십시오. 링크를 스크롤하고 포인트를 살펴보십시오. http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html – Raghunandan