문제

I have fragment that handles the camera. My problem is that it takes one photo and displays it on the imageView, just fine.

The second time I try to take a pic an OutOfMemory error. Any hints how to free the memory after the first photo?

 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);   
        System.out.println("tesstssaffsafdfsdfsd");
        switch (requestCode) {
        case TAKE_PICTURE:
            if (resultCode == Activity.RESULT_OK) {
                getActivity().getContentResolver().notifyChange(mUri, null);
                ContentResolver cr = getActivity().getContentResolver();
                try {
                    mPhoto = android.provider.MediaStore.Images.Media.getBitmap(cr, mUri);
                 ((ImageView)rootView.findViewById(R.id.snap)).setImageBitmap(mPhoto);
                } catch (Exception e) {
                     Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
                   }
              }
        }




 }

Here is the stack trace:

08-21 16:33:27.450: E/AndroidRuntime(1840): FATAL EXCEPTION: main
08-21 16:33:27.450: E/AndroidRuntime(1840): java.lang.OutOfMemoryError
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:650)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at   android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:722)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:790)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at com.example.lemonrelative.reading.AddReadingFrag_3.onActivityResult(AddReadingFrag_3.java:113)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:166)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.app.Activity.dispatchActivityResult(Activity.java:5390)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3178)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3225)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.app.ActivityThread.access$1100(ActivityThread.java:140)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1275)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.os.Looper.loop(Looper.java:137)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at android.app.ActivityThread.main(ActivityThread.java:4898)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at java.lang.reflect.Method.invokeNative(Native Method)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at  java.lang.reflect.Method.invoke(Method.java:511)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
08-21 16:33:27.450: E/AndroidRuntime(1840):     at dalvik.system.NativeStart.main(Native Method)
도움이 되었습니까?

해결책 2

A full size picture took by camera is pretty large. Let's say maybe 4 million pixels, if you are using RGB8888 to read as bitmap, it will cost about 16mb. If you want to load 2 pictures at the same time, it is likely to out of memory.

There are several ways could help.

  1. Read the bitmap with a sample size, which will lower the resolution of the bitmap. See this page for details.
  2. Use RGB565 instead of RGB8888 to read the bitmap. Since your bitmap will be opaque, the alpha channel will be useless.
  3. Recycle the old bitmap before creating a new one. This is what you can try fist.

See the sample code below.

ImageView mImage = xxx;
BitmapDrawable drawable = (BitmapDrawable) mImage.getDrawable(); 
if(drawable != null && drawable.getBitmap() != null){
    drawable.getBitmap().recycle();
    mImage.setImageDrawable(null); 
}
// set new bitmap here.

다른 팁

If the first bitmap's use is finished, recyle it or The easiest way is to add these 2 lines to the manifest in to the application tag

android:hardwareAccelerated="false"
android:largeHeap="true" 

But these are not recommended if you are building a memory efficient App But this really works.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top