2012-09-12 6 views
6

이미지를 사용하여 내 모든 활동의 배경으로 설정했지만 메모리 오버 플로우 문제가 발생하여 응용 프로그램이 중단되었습니다. 이제는 내 활동에서 일시 중지() 및 파괴()에 내 드로어 블을 바인딩 해제하고 이제는 뒤로 버튼을 누르면 빈 화면이 표시됩니다. 어떻게하면 여분의 메모리를 사용하지 않고도이 문제를 피할 수 있을까요? 항상 VM 우리 크기가 10MB 할당 못하게한다는 메모리 오버플로 오류가 발생하는 "/ 당김 @"= 배경 이제부터 비트 맵을 얻고있다 : drawable onPause()가 응답하지 않는 뒤로 탐색을 일으키고이 단계를 건너 뛰면 메모리 오버플로가 발생합니다.

protected void onPause(){ 
    super.onPause(); 
    unbindDrawables(findViewById(R.id.login_root)); 
} 

protected void onDestroy() { 
     unbindDrawables(findViewById(R.id.login_root)); 
     super.onDestroy(); 
     } 

private void unbindDrawables(View view) { 
    System.gc(); 
    Runtime.getRuntime().gc(); 
    if (view.getBackground() != null) { 
    view.getBackground().setCallback(null); 
    } 
    if (view instanceof ViewGroup) { 
     for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
     unbindDrawables(((ViewGroup) view).getChildAt(i)); 
     } 
    ((ViewGroup) view).removeAllViews(); 
    } 

처음에 내가 안드로이드를 사용하여 내 레이아웃을 팽창했다 (응용 프로그램을.) 그 drawable을 축소하지 않고 runtime.Now 그것은 VM이 unbindDrawables (..) 을 사용하지 않고 5 메가 바이트 (애플 리케이션) 할당 할 수 없다는 것을 말합니다. 분명히 표시되는 배경 이미지의 품질이 감소했지만 수 없습니다 13KB의 png 파일을 사용하고 있다면 요청을 처리하기 위해 JVM에서 5MB 또는 10MB 공간이 필요하다는 것을 이해해야합니다.

onCreate() 메서드에서 onResume() 메서드로 shift 레이아웃 문을 이동했지만 응용 프로그램의 뒤로 단추를 누르면 메모리가 부족합니다.

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    protected void onResume(){ 
     setContentView(R.layout.home); 
     Bitmap bmp; 
     ImageView background = (ImageView)findViewById(R.id.iv_home_background); 
     InputStream is = getResources().openRawResource(R.drawable.background); 
     bmp = BitmapFactory.decodeStream(is); 
     background.setImageBitmap(bmp); 

     super.onResume(); 
    } 

protected void onPause(){ 
     super.onPause(); 
     unbindDrawables(findViewById(R.id.home_root)); 
    } 


private void unbindDrawables(View view) { 
     System.gc(); 
     Runtime.getRuntime().gc(); 
     if (view.getBackground() != null) { 
     view.getBackground().setCallback(null); 
     } 
     if (view instanceof ViewGroup) { 
      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
      unbindDrawables(((ViewGroup) view).getChildAt(i)); 
      } 
     ((ViewGroup) view).removeAllViews(); 
     } 
    } 
+0

onDestroy()가 호출되면 onPause()도 호출됩니다. –

+0

@JohnSatriano가 설명한대로'onPause()'에서만 바인딩 해제. 하지만 여전히, 우리에게 당신의 onResume 함수를 보여 주시겠습니까? –

+0

Resume 함수에서 내 함수를 오버라이드하지 않았습니다. 나는 거기에서 무엇을해야하는지 전혀 모른다. – Atinder

답변

1

이 문제에 대한 해결 방법을 발견했습니다. 이제 런타임시 내 비트 맵을 크기가 매우 작은 크기로 조정 한 다음 내부 저장소에 저장합니다. 프로그램은 런타임에 저장 영역에서 크기 조정 된 비트 맵을 호출하고 거기에 없으면 드로어 블 폴더에서 크기 조정 비트 맵을 호출하고 크기를 조정 한 다음 저장소에 기록한 다음 뷰에 바인드합니다. 이렇게하면 언제든지 unbindDrawables 메서드를 호출 할 필요가 없으며 응용 프로그램 전체에서 응답 성이 유지됩니다. 지금 당장 걱정할 필요가있는 것은 비트 맵의 ​​품질입니다. 크기를 최대한 줄이면서 최대한의 크기를 찾으려면 크기 조정을해야합니다.

0

각 하위보기에 대해 GC를 호출하고 있습니다. 모든 언 바인드가 완료되면 한 번만 호출 해보십시오.

unbindDrawables(findViewById(R.id.login_root)); 
System.gc(); 

GC가 너무 많아서 GC를 너무 자주 호출하지 않아도됩니다. 사실 누수가 없다면 그것은 전혀 제 자리에 있어야합니다.

또한 png 파일 크기는 메모리의 비트 맵과 아무 관련이 없습니다. 여기에 대한 자세한 정보가 있습니다 http://developer.android.com/training/displaying-bitmaps/index.html