1

Having a problem with a custom button control which I have made. The button is defined in layout like this:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<ImageView
    android:layout_width="180dp"
    android:layout_height="180dp"
    android:layout_centerInParent="true"
    android:layout_margin="20dp"
    android:background="#fff"
    android:contentDescription="@string/my_button_info"
    android:src="@drawable/button_appearance" />

</merge>

and button_appearance is defined like this:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_pic_down"
  android:state_pressed="true" />
<item android:drawable="@drawable/button_pic"
  android:state_focused="true" />
<item android:drawable="@drawable/button_pic" />
</selector>

Now, when I push my button (click on the LinearLayout) I show it as a different bitmap and animate it as rotating, here is the animation:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1666"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="359" />

and I call it like this:

public void animateButton() {
    myButton.setEnabled(false);
    myButton.setImageDrawable(getContext().getResources().getDrawable(R.drawable.button_pic_spin));
    myButton.startAnimation(AnimationUtils.loadAnimation(context, R.anim.spinner_animation));
}

then, when the action it kicks off is done I stop it:

public void stopAndEnableButton() {
    myButton.setEnabled(true);
    myButton.setImageDrawable(getContext().getResources().getDrawable(R.drawable.button_appearance));
    ttcButton.clearAnimation();
}

I've received a few crashes from Crashlytics on the line just above where I call setImageDrawable. Crashlytics says:

Failed to allocate a 2869648 byte allocation with 1275632 free bytes and 1245KB until OOM

The weird thing is that the pngs here are all about 25K in size - and there are only 3 of them (2 referenced in button_appearance.xml and the plain one button_pic_spin) how are we getting to 2 Megabytes requirement when I try to swap in something which ought to be just 50K at most?

Is the problem that I ought to call ClearAnimation before I do setImageDrawable? Is the system actually trying to make a bunch of allocations for partially rotated bitmaps?

Kibi
  • 1,860
  • 1
  • 29
  • 39
  • 1
    What are the dimensions of the image? Take into account that size in disk is the compressed size. Image is uncompressed to use it – Claudio Redi May 31 '15 at 12:56
  • 635x635 pixels - would that account for it? – Kibi May 31 '15 at 13:08
  • It doesn't seem to be dramatic by itself but you're experiencing some memory issues. Do you have any other memory intensive activities? How much memory is in use by the app by the time it crashes? – Claudio Redi May 31 '15 at 23:31

4 Answers4

1

Memory allocation for images in Android depend on the pixels width and height of the image. Not the disk size.

Image Memory Size = width * height * 4 bytes (byte for red, byte for green, byte for blue and byte for alpha)

hasan
  • 23,815
  • 10
  • 63
  • 101
  • Thanks - did not realize that. Shrinking pngs and hope that will solve the problem – Kibi May 31 '15 at 13:32
  • I will extend my answer later to explain how to display high spec. images. which needs a zoom feature to really get advantage of its high spec. if you know what I mean. because some devices will not get advantage of it even if it is set to fit the screen because of the low screen resolution. – hasan May 31 '15 at 13:41
0

Your image is too large, try to lower the size, or try to load it with tips from second post here. (I am talking about those button pics)

Community
  • 1
  • 1
Dejan
  • 3,046
  • 3
  • 28
  • 43
-1

If you desperately need a solution provide "largeHeap":true in your application manifest.

Jai Kumar
  • 920
  • 1
  • 7
  • 14
  • No thanks, that's not how I want to solve the problem, I need to understand the actual thing, not paste over it – Kibi May 31 '15 at 13:12
-1

This error is thrown by the Java Virtual Machine (JVM) when an object cannot be allocated due to lack of memory space and also, the garbage collector cannot free some space.

Reference: https://stackoverflow.com/a/32245018/6111927

Add the below entities in your manifest file: android:hardwareAccelerated="false" , android:largeHeap="true" :

<application
android:allowBackup="true"
android:hardwareAccelerated="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
Community
  • 1
  • 1
Baduq
  • 1
  • 1