bisemanu
bisemanu

Reputation: 441

FATAL EXCEPTION in my app

In my app I have this error:

E/AndroidRuntime(16123): FATAL EXCEPTION: main
E/AndroidRuntime(16123): java.lang.RuntimeException: Unable to start activity ComponentInfo{it.bisemanuDEV.mathTools/it.bisemanuDEV.mathTools.MainActivity}: android.view.InflateException: Binary XML file line #58: Error inflating class <unknown>
E/AndroidRuntime(16123):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2073)
E/AndroidRuntime(16123):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2098)
E/AndroidRuntime(16123):    at android.app.ActivityThread.access$600(ActivityThread.java:138)
E/AndroidRuntime(16123):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1204)
E/AndroidRuntime(16123):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(16123):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(16123):    at android.app.ActivityThread.main(ActivityThread.java:4872)
E/AndroidRuntime(16123):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(16123):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(16123):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
E/AndroidRuntime(16123):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
E/AndroidRuntime(16123):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(16123): Caused by: android.view.InflateException: Binary XML file line #58: Error inflating class <unknown>
E/AndroidRuntime(16123):    at android.view.LayoutInflater.createView(LayoutInflater.java:613)
E/AndroidRuntime(16123):    at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
E/AndroidRuntime(16123):    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
E/AndroidRuntime(16123):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
E/AndroidRuntime(16123):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)

05-11 20:21:56.843: E/AndroidRuntime(16123): at android.view.LayoutInflater.rInflate(LayoutInflater.java:749) E/AndroidRuntime(16123): at android.view.LayoutInflater.inflate(LayoutInflater.java:489) E/AndroidRuntime(16123): at android.view.LayoutInflater.inflate(LayoutInflater.java:396) E/AndroidRuntime(16123): at android.view.LayoutInflater.inflate(LayoutInflater.java:352) E/AndroidRuntime(16123): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:361) E/AndroidRuntime(16123): at android.app.Activity.setContentView(Activity.java:2043) E/AndroidRuntime(16123): at it.bisemanuDEV.mathTools.MainActivity.onCreate(MainActivity.java:27) E/AndroidRuntime(16123): at android.app.Activity.performCreate(Activity.java:5191) E/AndroidRuntime(16123): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1082) E/AndroidRuntime(16123): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2037) E/AndroidRuntime(16123): ... 11 more E/AndroidRuntime(16123): Caused by: java.lang.reflect.InvocationTargetException E/AndroidRuntime(16123): at java.lang.reflect.Constructor.constructNative(Native Method) E/AndroidRuntime(16123): at java.lang.reflect.Constructor.newInstance(Constructor.java:417) E/AndroidRuntime(16123): at android.view.LayoutInflater.createView(LayoutInflater.java:587) E/AndroidRuntime(16123): ... 25 more E/AndroidRuntime(16123): Caused by: java.lang.OutOfMemoryError E/AndroidRuntime(16123): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) E/AndroidRuntime(16123): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:500) E/AndroidRuntime(16123): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:353) E/AndroidRuntime(16123): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:781) E/AndroidRuntime(16123): at android.content.res.Resources.loadDrawable(Resources.java:1969) E/AndroidRuntime(16123): at android.content.res.Resources.getDrawable(Resources.java:673) E/AndroidRuntime(16123): at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173) E/AndroidRuntime(16123): at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881) E/AndroidRuntime(16123): at android.graphics.drawable.Drawable.createFromXml(Drawable.java:818) E/AndroidRuntime(16123): at android.content.res.Resources.loadDrawable(Resources.java:1954) E/AndroidRuntime(16123): at android.content.res.TypedArray.getDrawable(TypedArray.java:601) E/AndroidRuntime(16123): at android.view.View.(View.java:3347) E/AndroidRuntime(16123): at android.widget.TextView.(TextView.java:494) E/AndroidRuntime(16123): at android.widget.Button.(Button.java:107) E/AndroidRuntime(16123): at android.widget.Button.(Button.java:103) E/AndroidRuntime(16123): ... 28 more

What can be the solution?

Upvotes: 1

Views: 508

Answers (3)

Tomer B
Tomer B

Reputation: 5465

The message is pretty self explanatory... You're running out of memory.

Check the parameters that you're passing to this method, there might simply be too many bitmaps being decoded and stored in memory.

Consider caching instead of pre-loading all the bitmaps - only load the bitmap when you actually need to use it. Then add it to a hasmap (from its ID to the actual bitmap). Before decoding a bitmap check if it is already in the map, if it is you don't need to decode it again. Be sure to check the size of the map before decoding new bitmaps, and clear the cache when necessary so you don't run out of memory.

Edit: Here's an example for how you could do it

Edit2: Here's the full class code. Hope I didn't make any typos.

public class CurrencyRateListAdapter extends BaseAdapter {
    // This variable is used for debug log (LogCat)
    private static final String TAG = "CC:CurrencyRateListAdapter";

    private LayoutInflater mInflater;
    private String[] mName; 
    private Integer[] mBitmapIds;
    private HashMap<Integer, Bitmap> mBitmaps;
    private Context mContext;

    private Cursor   mRateData;
    private double   mRate[];
    private String   mDisplayrate[];

    private int      mBaseCurrencyPosition;

    public CurrencyRateListAdapter(Context context, Integer[] name, Integer[] bitmapID, Cursor rate_data) {
        mInflater = LayoutInflater.from(context);
        mBitmaps = new HashMap<Integer, Bitmap>();
        mBitmapIds = bitmapID;
        mContext = context;
        mName = new String[name.length];

        for(int j=0; j<name.length; j++) {
            mName[j] = context.getString(name[j]);
        }

        mRateData = rate_data;

        // update currency rate
        updateCurrencyRate();

        // set default currency
        mBaseCurrencyPosition = 0;
    }

    @Override
    public void finalize() {
        Log.d(TAG, "Close SQL cursor...");
        mRateData.close();
    }

    public int getCount() {
        return mBitmapIds.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder  holder;             

        //Log.d(TAG, ">>>>> getView: position=" + Integer.toString(position));

        try {
            if(convertView == null) {
                // uses currencyratelist.xml to display each currency selection
                convertView = mInflater.inflate(R.layout.currencyratelist, null);
                // then create a holder for this view for faster access
                holder = new ViewHolder();

                holder.icon = (ImageView) convertView.findViewById(R.id.ratelist_icon);
                holder.name = (TextView) convertView.findViewById(R.id.ratelist_text);
                holder.rate = (TextView) convertView.findViewById(R.id.ratelist_ratetext);

                // store this holder in the list
                convertView.setTag(holder);
            } else {
                // load the holder of this view
                holder = (ViewHolder) convertView.getTag();
            }

            holder.icon.setImageBitmap(getIcon(mBitmapIds[position]));
            holder.name.setText(mName[position]);
            holder.rate.setText(mDisplayrate[position]);

        } catch (Exception e) {
            Log.e(TAG, "getView:" + e.toString());
        }

        //Log.d(TAG, "<<<<< getView: position=" + Integer.toString(position));

        return convertView;
    }

    public void SetBaseCurrencyIndex(int value) {
        mBaseCurrencyPosition = value;

        // update display rate
        double  rate_base = 1.0;

        if(mBaseCurrencyPosition < mRate.length) {
            rate_base = mRate[mBaseCurrencyPosition];
        }

        mDisplayrate = new String[mRateData.getCount()];

        for(int i=0; i<mRateData.getCount(); i++) {
            mDisplayrate[i] = String.format(Locale.US, "%.3f", mRate[i] / rate_base);
        }
    }

    public String getDisplayString(int position) {
        String result = "1.000";

        if(position < mRate.length) {
            result = mDisplayrate[position];
        }

        return result;
    }

    public void updateCurrencyRate() {
        Log.d(TAG, ">>>>> updateCurrencyRate");

        // update currency rate data
        mRateData.requery();

        mRate = new double[mRateData.getCount()];

        int cnt = mRateData.getCount();
        int colcnt = mRateData.getColumnCount();

        for(int i=0; i<cnt; i++) {
            if(mRateData.moveToPosition(i) == true) {
                if(colcnt == 1) {
                    // only currency rate data in the query result set
                    mRate[i] = mRateData.getDouble(0);
                } else {
                    // all data in the query result set
                    // So the rate data in the 2nd column (refer to CurrencyConverterDB class
                    mRate[i] = mRateData.getDouble(1);
                }
            } else {
                mRate[i] = 1.0;
            }
        }

        // deactive currency rate data
        mRateData.deactivate();

        Log.d(TAG, "<<<<< updateCurrencyRate");
    }   

    public double getCurrencyRate(int position) {
        double rate_sel = 1.0;

        if(position < mRate.length) {
            rate_sel = mRate[position];
        }

        return rate_sel;
    }

    /* class ViewHolder */
    private class ViewHolder {
        ImageView   icon;
        TextView    name;
        TextView    rate;
    }

    private Bitmap getIcon(Integer bitmapId) {
        Bitmap icon = mBitmaps.get(bitmapId);

        if (icon == null) {
            icon = BitmapFactory.decodeResource(mContext.getResources(), bitmapId);
            mBitmaps.put(bitmapId, icon);
        }

        return icon;
    }   
}

Upvotes: 1

Kiril Aleksandrov
Kiril Aleksandrov

Reputation: 2591

Your application memory is growing up too fast... This is how Android manages its memory per application: Lets say when you start your application, it has 10MB of memory. When your application uses for example 8MB, Android predicts that the remaining 2MB may not be sufficient. So Android gives your application some additional memory. So now you have 13MB (for example). This scenario repeats each time Android decides that the remainging memory may not be enough for your application. This way the used memory from the application is growing slowly and Android can manage it more effectively.

In your example you have a loop that is decoding images. This way the size of memory that your application uses grows too fast and Android has no time to gives you more memory.

Upvotes: 2

Udi Oshi
Udi Oshi

Reputation: 6867

you are getting java.lang.OutOfMemoryError because you are running this for loop

for(int i=0; i<bitmapID.length; i++) {
mIcon[i] = BitmapFactory.decodeResource(context.getResources(), bitmapID[i].intValue());

}

Note that decodeResource can cause that. I suggest you to try alternative ways as this function really takes lots of memory.

you may also want to calculate the size you need and than decode. in most cases you don't really need the full size.

Upvotes: 0

Related Questions