2011-03-29 2 views
0

내 앱에는 카메라 미리보기로 작동하는 활동이 있습니다. SurfaceView는 화면 전체에 걸쳐 펼쳐져 있으며, 위에 겹쳐진 여러 개의 항목이 있지만 너무 복잡하지는 않습니다. 이 활동은 다른 활동을 시작한 다음 카메라 미리보기로 다시 돌아갑니다.카메라 미리보기를 다시로드하기 전에 Android 메모리 문제가 발생했습니다.

리소스를 정리하고, 비트 맵을 재활용하고, 메모리 누수를 방지하는 등 매우 신중했습니다.이 앱을 실행하고 미친 것처럼 테스트 할 수 있지만 휴대 전화가 잠시 동안 켜져 있고 다른 앱이있는 경우 메모리를 사용하면 카메라 미리보기를 유지하는 활동을 다시 시작하거나 만들 때 자동 종료됩니다. 충돌을 재현하는 일반적인 테스트 케이스는 앱을 사용하고 스냅 사진 (처리를 트리거 함), 하위 활동을 반복해서 실행하는 것입니다. 앱에서 나와 무언가의 자원/그래픽을 비운 다음 내 앱을 다시 시작합니다. 여기

는 충돌시 몇 가지 로그 캣 출력입니다 :

내 활동은 모든 단계에서 로그인하는
03-29 14:20:02.109: ERROR/dalvikvm(6368): externalAllocPossible(): footprint 2756592 + extAlloc 15831356 + n 8640000 >= max 22409232 (space for 3821284) 
03-29 14:20:02.109: ERROR/dalvikvm-heap(6368): 8640000-byte external allocation too large for this process. 
03-29 14:20:02.109: ERROR/dalvikvm(6368): Out of memory: Heap Size=3835KB, Allocated=2835KB, Bitmap Size=15460KB, Limit=21884KB 
03-29 14:20:02.109: ERROR/dalvikvm(6368): Trim info: Footprint=5383KB, Allowed Footprint=5383KB, Trimmed=1548KB 
03-29 14:20:02.109: ERROR/GraphicsJNI(6368): VM won't let us allocate 8640000 bytes 

, 그래서 이것은 super.onCreate를 호출하고 상황에 맞는보기를 설정 사이에은 Activity.onCreate에서 발생 내 XML 레이아웃. 내 첫 번째 생각은 SurfaceHolder를 획득하는 과정이나 SurfaceHolder 메서드에서 발생하는 모든 작업이 타이트한 메모리 상황에서 너무 많이 일어날 수 있다는 것입니다. 그것은 내 XML 레이아웃을 구문 분석하고 뷰 개체를 구축하는 동안 setContentView에서 발생하는 것 같습니다.

내 카메라 미리보기 코드는 책과 기사에서 찾은 예제에서 가져 왔으므로 surfaceDestroyed에서 수행해야하는 추가 정리가 있는지 궁금합니다. 그 시점에서 가비지 수집을 시도해야합니까? 이 사고의 이유는 시스템에 앱이 메모리가 적은 상황에서 앱을 실행하기에 충분한 메모리가 있다는 것입니다. 그것은 내 자신의 응용 프로그램과 완전히 상관없이 정리하거나 시스템이 내 응용 프로그램을 위해 메모리를 충분히 빨리 회수 할 수 없도록해야합니다. 이해가 안되는 이유는 setContentView가 너무 많은 새 메모리를 할당하려고 시도하는 이유입니다.

여기 내 표면 콜백 코드와 미리보기를 중지하고 onPause()에서 카메라를 분리 한 onResume() 그것을 획득 활동

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.camera_preview); 

    // crash occurs here 

    // ...other stuff 

    initControls(); 
} 

private void initControls() 
{  
    previewHolder = preview.getHolder(); 
    previewHolder.addCallback(surfaceCallback); 
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    // ...other stuff 
} 


SurfaceHolder.Callback surfaceCallback = new Callback() { 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.d(ApplicationEx.LogTag, "surfaceDestroyed"); 
     camera.stopPreview(); 
     camera.release(); 
     camera = null; 
     isPreviewRunning = false; 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     Log.d(ApplicationEx.LogTag, "surfaceCreated"); 
     camera = Camera.open(); 

     try 
     { 
      camera.setPreviewDisplay(previewHolder); 
     } 
     catch(Throwable t) 
     { 

     } 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
    { 
     Log.d(ApplicationEx.LogTag, "surfaceChanged"); 
     if (isPreviewRunning) 
     { 
      Log.d(ApplicationEx.LogTag, "preview is running, stop preview"); 
      camera.stopPreview(); 
      isPreviewRunning = false; 
     } 
     Camera.Parameters parameters = camera.getParameters(); 
     setPreviewAndPictureSize(parameters, width, height); 
     parameters.setPictureFormat(PixelFormat.JPEG); 
     parameters.setJpegQuality(85); 
     camera.setParameters(parameters); 
     camera.startPreview(); 
     isPreviewRunning = true; 
     Log.d(ApplicationEx.LogTag, "end surfaceChanged"); 

    } 
}; 

답변

2

에서 어떤 일이 일어나는지의 의역이다. 다른 어떤 것에 관계없이 지금 당장 카메라를 묶어두고 사용자가 홈을 누를 때 다른 응용 프로그램이 카메라를 사용하지 못하게 할 것입니다.

은 (BTW, 나는 오랫동안이 잘못을했고 지난 몇 개월 동안 내 책에 수정)

내가 확실하지 오전하지만이, 메모리 상황에 도움이 될 가능성이있다. 정확히 8640000 바이트 할당 (실제로는 정말 큽니다)을 요구하는 것을 좁힐 수 있다면 도움이 될 것입니다. 레이아웃의 일부 배경 이미지일까요?

+0

당신이 기뻤습니다. Adv Busy Coder 's Guide의 이전 복사본에서 SurfaceHolder.Callback을 인식 할 수 있습니다. 업데이트 된 획득/릴리스 논리에 감사드립니다. 나는 거기에 8MB의 것을 아무것도 가지고 있지 않습니다. 레이아웃에 자리 표시 자 이미지가 있었는데 (에뮬레이터에서 미리보기) 위에 오버레이를 디자인했지만 바로 그게 약 350k였습니다. 나는 그것이 도움이되는지보기 위해 그것을 제거했다. – Rich

+0

@ 리치 : PNG/JPG 파일의 350k는 일단 압축 해제되면 훨씬 더 커질 것입니다. – CommonsWare

+0

예 ... 미리보기 이미지는 앱 출력에서 ​​가져온 것이므로 레이아웃에 포함하기 전에 축소하지 않았습니다. 1600h x 1200w x 4 (argb) = 거의 8MB. 아마도 8.64M까지 반올림하는 메타 데이터일까요? 도움에 다시 한번 감사드립니다. – Rich

관련 문제