0

I am trying to load a jpeg photo with a size of 965KB on my android phone. The code is below. When I run the code, the app crashes.

Button _btn = (Button) findViewById(R.id.btn1);
_btn.setOnClickListener(new View.OnClickListener() {

     @Override
      public void onClick(View view) {
           Drawable _draw  = getResources().getDrawable(R.drawable.sea, null);
    }
});

This is the crash log.

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.a3sumatch.multipart, PID: 29240 java.lang.OutOfMemoryError: Failed to allocate a 362797068 byte allocation with 8388608 free bytes and 254MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609) at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444) at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080) at android.content.res.Resources.loadDrawableForCookie(Resources.java:2761) at android.content.res.Resources.loadDrawable(Resources.java:2654) at android.content.res.Resources.getDrawable(Resources.java:833) at com.a3sumatch.multipart.MainActivity$1.onClick(MainActivity.java:40) at android.view.View.performClick(View.java:5205) at android.view.View$PerformClick.run(View.java:21176) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:171) at android.app.ActivityThread.main(ActivityThread.java:5611) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)

Levon Petrosyan
  • 8,815
  • 8
  • 54
  • 65
  • 1
    Possible duplicate of [Android:java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM](https://stackoverflow.com/questions/32244851/androidjava-lang-outofmemoryerror-failed-to-allocate-a-23970828-byte-allocatio) – petey Aug 29 '17 at 14:10
  • Do you know that first: Android likes to scale Images depending on screen resolution? So it may be much bigger than the original. Second a Bitmap is an uncompressed Format and holds an int per pixel, whereas JPEG may hardly be compressed – Rafael T Aug 29 '17 at 14:10

1 Answers1

2

I am trying to load a jpeg photo with a size of 965KB on my android phone

That is an absolutely massive photo. JPEG, like PNG and WebP, is a compressed file format. To put that in perspective, a 3229x2480 photo of my balding head is 829.3KB in a JPEG. I would expect yours to be a bit larger in each dimension. That resolution is higher than the resolution of any Android device screen that I know of.

Your OutOfMemoryError is for a 362797068-byte allocation. A Bitmap is an uncompressed version of the image. 362797068 bytes is equivalent to about a 9524x9524 square image (and 4 bytes/pixel).

So, you need to do two things:

  1. If you have this image in res/drawable/, move it to res/drawable-nodpi/

  2. Reduce the resolution of this image by at least a factor of four along each dimension

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • sorry, I still don't understand. Why will android try to allocate a memory of about 345M for a photo of no more than 1M? –  Aug 29 '17 at 14:23
  • 1
    @StoneLai: First, quoting my answer, "JPEG, like PNG and WebP, is a compressed file format... A `Bitmap` is an uncompressed version of the image." Compressed files can easily be only 1-10% of the size of the uncompressed data. Second, if you put the image in `res/drawable/` as I suspect, you are telling Android that you designed your image for `-mdpi` displays and that Android should upscale the image for higher-density screens. – CommonsWare Aug 29 '17 at 14:29