안 드 로 이 드 쓰레기 회수 메커니즘 메모리 유출 문제 해결
1.단일 사례 를 작성 할 때 자주 발생 하 는 오류.
오류 모드:
public class Foo{
private static Foo foo;
private Context mContext;
private Foo(Context mContext){
this.mContext = mContext;
}
// ,
public static Foo getInstance(Context mContext){
if(foo == null)
foo = new Foo(mContext);
return foo;
}
public void otherAction(){
mContext.xxxx();
….
}
}
오류 원인:만약 에 저희 가 Activity A 나 다른 곳 에서 Foo.getInstance()를 사용 할 때 저 희 는 항상'this'나'mContext'(이 변수 도 this 를 가리 키 는 것)를 손 쉽게 씁 니 다.생각해 보 세 요.현재 우리 가 사용 하고 있 는 Foo 는 하나의 예 입 니 다.초기 화 된 후에 메모리 와 계속 존재 하 는 것 을 의미 합 니 다.나중에 호출 할 때 이번 Foo 대상 을 만 들 지 않 습 니 다.그러나 Foo 의'mContext'변 수 는 항상 Activity A 의'Context'를 가지 고 있 기 때문에 Activity A 는 onDestroy 방법 을 실행 하 더 라 도 자신 을 소각 할 수 없습니다.그러나"applicationContext"는 다 릅 니 다.저희 애플 리 케 이 션 과 함께 존재 합 니 다.(중간 에 삭 제 될 수도 있 지만 자동 으로 reCreate 될 수도 있 습 니 다.)따라서 Foo 의"mContext"는 특정한 Activity 의 인용 을 가지 고 있어 서 소각 할 수 없 을 것 이 라 고 걱정 하지 않 아 도 됩 니 다.
올 바른 방식:
public class Foo{
private static Foo foo;
private Context mContext;
private Foo(Context mContext){
this.mContext = mContext;
}
// ,
public static Foo getInstance(Context mContext){
if(foo == null)
foo = new Foo(mContext.getApplicationContext());
return foo;
}
public void otherAction(){
mContext.xxxx();
….
}
}
2.익명 내부 클래스 를 사용 할 때 자주 발생 하 는 오류오류 모드:
public class FooActivity extends Activity{
private TextView textView;
private Handler handler = new Handler(){
@override
public void handlerMessage(Message msg){
}
};
@override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
setContextView(R.layout.activity_foo_layout);
textView = (TextView)findViewById(R.id.textView);
handler.postDelayed(new Runnable(){
@override
public void run(){
textView.setText(“ok”);
};
},1000 * 60 * 10);
}
}
오류 원인:FooActivity 의 finish 방법 을 실 행 했 을 때 지 연 된 메 시 지 는 처리 되 기 전에 메 인 스 레 드 메시지 큐 에 10 분 동안 존재 합 니 다.이 메시지 에는 Handler 의 인용 이 포함 되 어 있 습 니 다.Handler 는 익명 의 내부 클래스 의 인 스 턴 스 로 외부 FooActivity 의 인용 을 가지 고 있 기 때문에 FooActivity 를 회수 할 수 없습니다.이 로 인해 FooActivity 가 보유 한 많은 자원 을 회수 하지 못 해 메모리 유출 이 발생 했다.
위의 new Runnable 을 주의 하 세 요.여기 도 익명 의 내부 클래스 로 이 루어 집 니 다.또한 FooActivity 의 인용 도 가지 고 있 고 FooActivity 가 회수 되 는 것 을 막 을 수 있 습 니 다.
정적 익명 내부 클래스 인 스 턴 스 는 외부 클래스 의 인용 을 가지 고 있 지 않 습 니 다.
올 바른 방식:
public class FooActivity extends Activity{
private TextView textView;
private static class MyHandler extends Handler {
private final WeakReference<FooActivity> mActivity;
public MyHandler(FooActivity activity) {
mActivity = new WeakReference<FooActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
FooActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
private final MyHandler handler = new MyHandler(this);
@override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
setContextView(R.layout.activity_foo_layout);
textView = (TextView)findViewById(R.id.textView);
handler.postDelayed(new MyRunnable(textView),1000 * 60 * 10);
}
private static class MyRunnable implements Runnable{
private WeakReference<TextView> textViewWeakReference;
public MyRunnable(TextView textView){
textViewWeakReference = new WeakReference<TextView>(textView);
}
@override
public void run(){
final TextView textView = textViewWeakReference.get();
if(textView != null){
textView.setText("OK");
}
};
}
}
3.handler 를 사용 한 후에 onDestroy 에서 handler.removeCallbacks AndMessages(object token)를 기억 하 십시오.
handler.removeCallbacksAndMessages(null);
// removeCallbacksAndMessages, null , handler Runnable Message, onDestroy 。
메모리 누 출 을 막 기 위해 개발 중 주의해 야 할 점:여러분,일부 NO 에 숫자 가 추 가 된 것 을 주의 하 세 요.사실은 이런 것들 은 능력 적 으로 YES 인 데 왜 NO 라 고 하 죠?다음 설명:
숫자 1:Activity 를 시작 하 는 것 은 이 클래스 에서 가능 하지만 새로운 task 를 만들어 야 합 니 다.일반적인 상황 은 추천 하지 않 습 니 다.
숫자 2:이 클래스 에서 layot inflate 를 제거 하 는 것 은 합 법 적 이지 만 시스템 의 기본 테마 스타일 을 사용 합 니 다.어떤 스타일 을 사용자 정의 하면 사용 되 지 않 을 수도 있 습 니 다.
숫자 3:receiver 가 null 일 때 4.2 이상 버 전에 서 점성 방송의 현재 값 을 가 져 올 수 있 습 니 다.(무시 해도 된다)
주:ContentProvider,BroadcastReceiver 가 상기 표 에 있 는 이 유 는 내부 방법 에 context 가 사용 되 기 때 문 입 니 다.
자,여기 서 표를 보 겠 습 니 다.Activity 와 Application 에 중심 을 두 고 볼 수 있 습 니 다.UI 와 관련 된 방법 은 기본적으로 애플 리 케 이 션 을 권장 하지 않 거나 사용 할 수 없습니다.그리고 앞의 세 가지 조작 은 애플 리 케 이 션 에 나타 날 수 없습니다.실제로 조금 만 파악 하면 UI 와 관련 된 모든 것 은 Activity 를 Context 로 처리 해 야 한다.다른 일부 조작,Service,Activity,Application 등 인 스 턴 스 는 모두 가능 합 니 다.물론 Context 참조 소지 에 주의 하여 메모리 누 출 을 방지 합 니 다.
이상 은 본문의 전체 내용 이 므 로 여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.