마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

SurfaceView 를 사용해 카메라 촬영 앱을 개발했는데 2번째 촬영시 계속 메모리아웃 에러가 발생합니다.. 안드로이드 시작한지가 얼마 안되어 감을 못잡겠는데 어떻게 해결해야할까요? 고수님들 부탁드립니다!!!

0 추천
03-02 16:28:31.601  17479-17479/com.example.issue_camera9 E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.issue_camera9, PID: 17479
    java.lang.OutOfMemoryError
            at android.graphics.Bitmap.nativeCreate(Native Method)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:928)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:901)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:833)
            at com.example.issue_camera9.SurfaceCamera.Preview$2.onPictureTaken(Preview.java:303)
            at android.hardware.Camera$EventHandler.handleMessage(Camera.java:987)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5602)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)

프로젝트 파일 링크 공유합니다.

https://www.dropbox.com/s/rauxnfn0zs2giu5/issue_camera9.zip?dl=0

감사합니다!!!

살별패 (180 포인트) 님이 2015년 3월 2일 질문

1개의 답변

0 추천
SurfaceView를 통해서 사진 촬영 이후 기존 Bitmap에 대해 해제를 시켜주지 않아 발생하는 현상으로 보이네요.

사진 촬영후 저장한 bitmap을 외부저장장치 등에 저장한 이후에 bitmap 에 대해 null 처리를 해주거나 recycle 해주세요.

Bitmap과 메모리 관련 내용을 구글링 하시면 될 것 같습니다.
빅클라인 (4,520 포인트) 님이 2015년 3월 2일 답변
빅클라인님 답변 감사합니다.
계속 구글링해서 수정을 하는게 해결이 잘안됩니다...

    @Subscribe
    public void showTakenPicture(TakePicture e) {
        mBitmap = e.picture;
        mSquaredView.setImageBitmap(mBitmap);
        mCurrentMode = MODE_PICTURE_EDIT;
        findViewById(R.id.picture_save_button).setVisibility(View.VISIBLE);
        findViewById(R.id.picture_save_button).setOnClickListener(mClickListener);
    }

    Button.OnClickListener mClickListener = new View.OnClickListener() {
                        public void onClick(View v) {
                            switch (v.getId()) {
                                case R.id.picture_save_button:
                                    mCurrentMode = MODE_CAMERA_PREVIEW;
                                    mSquaredView.setImageBitmap(null);
                                    SaveBitmapToFile();
                    -> 이미지 파일 저장
                    mPreview.retake();
                    findViewById(R.id.picture_save_button).setVisibility(View.GONE);
                    break;
            }
        }
    };


    private void SaveBitmapToFile() {
        File picFile = getOutputMediaFile();
        try {
            FileOutputStream fos = new FileOutputStream(picFile);
            if (mBitmap != null) {
                mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
            }
            fos.close();
            if (mBitmap != null) {
                mBitmap.recycle();
                Log.d(TAG, "recycle");
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

SaveBitmapToFile 에서 리사이클 했는데도 계속 에러가 뜹니다..
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap src = BitmapFactory.decodeFile("/sdcard/image.jpg", options);
Bitmap resized = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true);

이런식으로 BitmapFactory의 option을 주어서 사용해보시기 바랍니다.
recycle도 실제 compress 라인 바로 밑에 해주시고,
그다음에 steam을 close해보세요
...