2011-11-24 2 views
4

두 가지 간단한 작업이 있습니다. AB입니다. 사용자는 버튼을 눌러 A에서 B을 시작한 다음 뒤로 버튼을 눌러 A으로 돌아갑니다.OnDestroy에서 비트 맵 다시 쓰기 - 활동을 다시 시작할 때 '재생 된 비트 맵을 사용하려고합니다'

액티비티 B에서는 액티비티 B에서 사용 된 일부 배경 이미지를 리사이징합니다. 내가 이해하려고 노력하는 이유는 액티비티 B이 다시 시작될 때 '재활용 된 비트 맵을 사용하려고합니다.'입니다. 당연히 비트 맵은 onCreate() 메서드에서 다시로드 될 것입니까? 활동이 처음 시작되었을 때처럼. 여기

내 예제 코드입니다 :

public class ActivityB extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
     setContentView(R.layout.selectionpage);  
    } 

    @Override 
    public void onDestroy() {  
     ImageView iv = (ImageView) findViewById(R.id.imageView1); 
     ((BitmapDrawable)iv.getDrawable()).getBitmap().recycle(); 
     LinearLayout ll = (LinearLayout) findViewById(R.id.linearLayout1); 
     ((BitmapDrawable)ll.getBackground()).getBitmap().recycle(); 
     super.onDestroy(); 
    } 
} 

내가에서 활동 B를 실행하는 데 사용하는 코드 A

 Intent intent = new Intent(ActivityA.this, ActivityB.class); 
    startActivity(intent); 

selectionpage.XML :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/linearLayout1" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:background="@drawable/backgroundimage"> 

     <ImageView 
      android:id="@+id/imageView1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:src="@drawable/selectionimage"/> 
     </LinearLayout>     

것은이 부분은 관련이있을 수 . 나는 잘 모르겠다. 나는 활동 B를 시작한 후에도 파괴 된 후에도 MAT를 사용하여 메모리 힙을 분석 할 때 내 활동의 인스턴스를 볼 수 있습니다. GC 뿌리에 대한 경로는 Java.lang.Thread와 ContextImpl을 거친 것으로 보인다.

답변

1

ImageView iv & LinearLayout ll이 여전히 재활용 비트 맵을 가리키고 있기 때문에 오류가 발생합니다. onDestroy() 안에 직접 재활용 할 필요가 없습니다. 비트 맵은 시스템에서 필요하지 않으면 해제됩니다.

+1

그래를 사용하십니까. 저는 바보입니다. XML 파일이 어떻게 작동하는지 몰랐습니다. 한가지주의 할 점은 여러 프로그램을로드 한 후에 메모리 오류가 발생하는 것 같아요. 일부 이미지는 더 이상 사용되지 않지만 GC는 이미지를 제거하지 않는 것 같습니다. 나는 그 (것)들에 recycle()를 요구하고있다 - 나는 GC를 그 (것)들을 즉시 청소하기 위하여보다는 오히려 기다리기 위하여 통지하기 위하여 믿는다. 어쨌든, 나는 방황하고있다. 답해 주셔서 감사합니다 – Wozza

+1

이것은 안드로이드의 모든 버전에 해당하지 않습니다 :'안드로이드 2.3.3 (API 레벨 10) 이하에서는 비트 맵의 ​​배경 픽셀 데이터가 네이티브 메모리에 저장됩니다. Dalvik 힙에 저장된 비트 맵 자체와는 별개입니다. 네이티브 메모리의 픽셀 데이터는 예측 가능한 방식으로 해제되지 않으므로 잠재적으로 응용 프로그램이 메모리 제한을 잠시 초과하여 충돌을 일으킬 수 있습니다. http://developer.android.com/training/displaying-bitmaps/manage-memory.html # inBitmap – ForceMagic

1

오랜 기간 동안 활동을 유지하고있는 별도의 스레드에서 해당 활동에 대한 참조가있는 경우 메모리 누수가 발생할 수 있습니다.

이로 인해 이전 활동에서 iv 및 ll이 재활용 된 후에 비트 맵을 계속 사용할 수 있습니다. iv.setImageDrawable (null) 및 ll.setBackgroundDrawable (null)을 수행 할 수 있지만 이러한 비트 맵은 시스템에서 작성하므로 다시 매핑 할 필요가 없습니다.

메모리 문제가 발생하여 재활용을 시도하고 계신 것 같습니까? 위에서 언급 한 누설로 더 잘 설명 될 수 있습니다.

+0

당신이 옳은 기억 문제가 있습니다. 나는 높거나 낮은 것을 검색 했으므로이 활동으로 인해 메모리 누출이 발생할 수있는 참조를 찾을 수 없습니다. 내가 B 액티비티를 시작할 때 3Mb의 힙 공간을 잃는 이유를 이해할 수 없기 때문에 재활용하려고했습니다. 활동을 마감 할 때 나는 그것을 되돌릴 수없는 것처럼 보입니다. 활동을 다시 시작하면 힙이 몇 kbs 만 증가합니다. 내가 말했듯이, 나는 메모리 덤프를 조사해 보았지만 그 활동이 여전히 존재하는 것처럼 보일 수있다.하지만 몇 번이나 활동을 멈추고/시작해도 그것은 단지 1 장이다. – Wozza

+0

B에서 뭐하고 있니? 모든 스레드 또는 비동기 작업? 내면의 수업은 있니? 드로어 블 (drawable) 또는 뷰 (view)와 같은 것을 정적 변수로 설정합니까? 활동의 인스턴스를 전혀 보유하지 않습니까? – FunkTheMonk

+0

B의 문제는 AdMob (배너 광고 있음)과 관련이 있습니다. AdMob 제거를 시도했지만 모든 것이 잘 정리 된 것 같습니다. 내 생각에 AdMob은 내 맥락을 지키고 자체를 파괴하지 않으므로 다른 어떤 것도 청소하지 못하게됩니다. – Wozza

-1

코드로 작성해야합니다. 코드에서 비트 맵 오브젝트를 시작하고 Imageview.setImageBitmap (비트 맵)

Bitmap bitmap; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.selectionpage); 
    bitmap = new BitmapFactory.decode... 
    yourImageView.setImageBitmap(bitmap); 

} 
@Override 
public void onDestroy() {  

    super.onDestroy(); 
    // do recycle bitmap here 
    bitmap.recycle(); 
} 
+0

이 코드는 높은 기회가 있습니다 : 치명적인 예외 : java.lang.RuntimeException : Canvas : 재활용 된 비트 맵 [email protected]을 사용하려고합니다. 이는 캔버스가 여전히 그것을 사용하는 동안 재활용이 너무 일찍 호출되었음을 의미합니다. – ForceMagic

관련 문제