safaiyeh
safaiyeh

Reputation: 1715

Emulator crash, java.lang.OutOfMemoryError

For my app, I got a bunch of switch methods, for a drawer. After clicking 3 items on the drawer, the fourth one causes the app to crash and I get this error.

java.lang.OutOfMemoryError
        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587)
        at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:422)
        at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)
        at android.content.res.Resources.loadDrawable(Resources.java:2110)
        at android.content.res.Resources.getDrawable(Resources.java:700)
        at android.widget.ImageView.resolveUri(ImageView.java:638)
        at android.widget.ImageView.setImageResource(ImageView.java:367)
        at icykum.JasonSafaiyeh.cocg.troopScreen$PlaceholderFragment.onCreateView(troopScreen.java:636)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        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:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)

Troop Screen:

public class troopScreen extends ActionBarActivity
        implements TroopNavigationDrawerFragment.NavigationDrawerCallbacks {

    /**
     * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
     */
    private TroopNavigationDrawerFragment mNavigationDrawerFragment;

    /**
     * Used to store the last screen title. For use in {@link #restoreActionBar()}.
     */
    private CharSequence mTitle;
    public int firstTroop = 0,
            secondTroop = 0,
            thirdTroop = 0,
            fourthTroop = 0,
            fifthTroop = 0,
            description = 0,
            troop_costs = 0,
            troop_stats = 0,
            troop_stats2 = 0;

    public String firstTroopText = "",
            secondTroopText = "",
            thirdTroopText = "",
            fourthTroopText = "",
            fifthTroopText = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_troop_screen);

        mNavigationDrawerFragment = (TroopNavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();

        // Set up the drawer.
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));
    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
                .commit();
    }

    //Titles
    public String onSectionAttached(int number) {
        switch (number) {
            case 1:
                mTitle = "Barbarian";
                break;
            case 2:
                mTitle = "Archer";
                break;
            case 3:
                mTitle = "Goblin";
                break;
            case 4:
                mTitle = "Giant";
                break;
            case 5:
                mTitle = "Wall Breaker";
                break;
            case 6:
                mTitle = "Balloon";
                break;
            case 7:
                mTitle = "Wizard";
                break;
            case 8:
                mTitle = "Healer";
                break;
            case 9:
                mTitle = "Dragon";
                break;
            case 10:
                mTitle = "P.E.K.K.A";
                break;
            case 11:
                mTitle = "Minion";
                break;
            case 12:
                mTitle = "Hog Rider";
                break;
            case 13:
                mTitle = "Valkyrie";
                break;
            case 14:
                mTitle = "Golem";
                break;
            case 15:
                mTitle = "Witch";
                break;
            case 16:
                mTitle = "Barbarian King";
                break;
            case 17:
                mTitle = "Archer Queen";
                break;
        }
        return (String) mTitle;
    }

    public int getFirstTroop(int number){
        switch(number){
            case 1:
                firstTroop = R.drawable.barb;
                break;
            case 2:
                firstTroop = R.drawable.archer;
                break;
            case 3:
                firstTroop = R.drawable.goblin;
                break;
            case 4:
                firstTroop = R.drawable.giant;
                break;
            case 5:
                firstTroop = R.drawable.wb;
                break;
            case 6:
                firstTroop = R.drawable.balloon;
                break;
            case 7:
                firstTroop = R.drawable.wizard;
                break;
            case 8:
                firstTroop = R.drawable.healer;
                break;
            case 9:
                firstTroop = R.drawable.dragon;
                break;
        }
        return firstTroop;
    }

    public String getFirstTroopText(int number){
        switch(number){
            case 1:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 2:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 3:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 4:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 5:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 6:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 7:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 8:
                firstTroopText = "Lvl 1 & 2";
                break;
            case 9:
                firstTroopText = "Level 1";
                break;
        }
        return firstTroopText;
    }

    public int getSecondTroop(int number){
        switch(number){
            case 1:
                secondTroop = R.drawable.barb2;
                break;
            case 2:
                secondTroop = R.drawable.archer2;
                break;
            case 3:
                secondTroop = R.drawable.goblin2;
                break;
            case 4:
                secondTroop = R.drawable.giant2;
                break;
            case 5:
                secondTroop = R.drawable.wb2;
                break;
            case 6:
                secondTroop = R.drawable.balloon2;
                break;
            case 7:
                secondTroop = R.drawable.wizard2;
                break;
            case 8:
                secondTroop = R.drawable.healer2;
                break;
            case 9:
                secondTroop = R.drawable.dragon2;
                break;
        }
        return secondTroop;
    }

    public String getSecondTroopText(int number){
        switch(number){
            case 1:
                secondTroopText = "Lvl 3 & 4";
                break;
            case 2:
                secondTroopText = "Lvl 3 & 4";
                break;
            case 3:
                secondTroopText = "Lvl 3 & 4";
                break;
            case 4:
                secondTroopText = "Lvl 3 & 4";
                break;
            case 5:
                secondTroopText = "Lvl 3 & 4";
                break;
            case 6:
                secondTroopText = "Lvl 3 & 4";
                break;
            case 7:
                secondTroopText = "Level 3";
                break;
            case 8:
                secondTroopText = "Lvl 3 & 4";
                break;
            case 9:
                secondTroopText = "Level 2";
                break;
        }
        return secondTroopText;
    }

    public int getThirdTroop(int number){
        switch(number){
            case 1:
                thirdTroop = R.drawable.barb3;
                break;
            case 2:
                thirdTroop = R.drawable.archer3;
                break;
            case 3:
                thirdTroop = R.drawable.goblin3;
                break;
            case 4:
                thirdTroop = R.drawable.giant3;
                break;
            case 5:
                thirdTroop = R.drawable.wb3;
                break;
            case 6:
                thirdTroop = R.drawable.balloon3;
                break;
            case 7:
                thirdTroop = R.drawable.wizard3;
                break;
            // No 8
            case 9:
                thirdTroop = R.drawable.dragon3;
                break;
        }
        return thirdTroop;
    }

    public String getThirdTroopText(int number){
        switch(number){
            case 1:
                thirdTroopText = "Level 5";
                break;
            case 2:
                thirdTroopText = "Level 5";
                break;
            case 3:
                thirdTroopText = "Level 5";
                break;
            case 4:
                thirdTroopText = "Level 5";
                break;
            case 5:
                thirdTroopText = "Level 5";
                break;
            case 6:
                thirdTroopText = "Level 5";
                break;
            case 7:
                thirdTroopText = "Level 4";
                break;
            // no 8
            case 9:
                thirdTroopText = "Level 3";
                break;
        }
        return thirdTroopText;
    }

    public int getFourthTroop(int number){
        switch(number){
            case 1:
                fourthTroop = R.drawable.barb4;
                break;
            case 2:
                fourthTroop = R.drawable.archer4;
                break;
            case 3:
                fourthTroop = R.drawable.goblin4;
                break;
            case 4:
                fourthTroop = R.drawable.giant4;
                break;
            case 5:
                fourthTroop = R.drawable.wb4;
                break;
            case 6:
                fourthTroop = R.drawable.balloon4;
                break;
            case 7:
                fourthTroop = R.drawable.wizard4;
                break;
            //No 8
            case 9:
                fourthTroop = R.drawable.dragon4;
                break;
        }
        return fourthTroop;
    }

    public String getFourthTroopText(int number){
        switch(number){
            case 1:
                fourthTroopText = "Level 6";
                break;
            case 2:
                fourthTroopText = "Level 6";
                break;
            case 3:
                fourthTroopText = "Level 6";
                break;
            case 4:
                fourthTroopText = "Level 6";
                break;
            case 5:
                fourthTroopText = "Level 6";
                break;
            case 6:
                fourthTroopText = "Level 6";
                break;
            case 7:
                fourthTroopText = "Level 5";
                break;
            // no 8
            case 9:
                fourthTroopText = "Level 4";
                break;
        }
        return fourthTroopText;
    }

    public int getFifthTroop(int number){
        switch(number){
            //#1-6 no fifth troop
            case 7:
                fifthTroop = R.drawable.wizard5;
                break;
            //no 8
            //no 9
        }
        return fifthTroop;
    }

    public String getFifthTroopText(int number){
        switch(number){
            //#1-6 no fifth troop
            case 7:
                fifthTroopText = "Level 6";
                break;
            // no 8
            // no 9
        }
        return fifthTroopText;
    }

    public int getDescription(int number){
        switch (number){
            case 1:
                description = R.drawable.barb_description;
                break;
            case 2:
                description = R.drawable.arch_description;
                break;
            case 3:
                description = R.drawable.gob_description;
                break;
            case 4:
                description = R.drawable.giant_description;
                break;
            case 5:
                description = R.drawable.wb_description;
                break;
            case 6:
                description = R.drawable.balloon_description;
                break;
            case 7:
                description = R.drawable.wizard_description;
                break;
            case 8:
                description = R.drawable.healer_description;
                break;
            case 9:
                description = R.drawable.dragon_description;
                break;
        }
        return description;
    }

    public int getTroop_costs(int number){
        switch (number){
            case 1:
                troop_costs = R.drawable.barb_costs;
                break;
            case 2:
                troop_costs = R.drawable.arch_costs;
                break;
            case 3:
                troop_costs = R.drawable.gob_costs;
                break;
            case 4:
                troop_costs = R.drawable.giant_costs;
                break;
            case 5:
                troop_costs = R.drawable.wb_costs;
                break;
            case 6:
                troop_costs = R.drawable.balloon_costs;
                break;
            case 7:
                troop_costs = R.drawable.wizard_costs;
                break;
            case 8:
                troop_costs = R.drawable.healer_costs;
                break;
            case 9:
                troop_costs = R.drawable.dragon_costs;
        }
        return troop_costs;
    }

    public int getTroop_stats(int number){
        switch(number){
            case 1:
                troop_stats = R.drawable.barb_stats;
                break;
            case 2:
                troop_stats = R.drawable.arch_stats;
                break;
            case 3:
                troop_stats = R.drawable.gob_stats;
                break;
            case 4:
                troop_stats = R.drawable.giant_stats;
                break;
            case 5:
                troop_stats = R.drawable.wb_stats;
                break;
            case 6:
                troop_stats = R.drawable.balloon_stats;
                break;
            case 7:
                troop_stats = R.drawable.wizard_stats;
                break;
            case 8:
                troop_stats = R.drawable.healer_stats;
                break;
            case 9:
                troop_stats = R.drawable.dragon_stats;
                break;
        }
        return troop_stats;
    }

    public int getTroop_stats2(int number){
        switch(number){
            case 1:
                troop_stats2 = R.drawable.barb_stats2;
                break;
            case 2:
                troop_stats2 = R.drawable.arch_stats2;
                break;
            // Case 3... No Goblin
            // Case 4... No Giant
            case 5:
                troop_stats2 = R.drawable.wb_stats2;
                break;
            case 6:
                troop_stats2 = R.drawable.balloon_stats2;
                break;
            //Case 7... No Wizard
            //No 8 or 9
        }
        return troop_stats2;
    }

    public void restoreActionBar() {

        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle(mTitle);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            // Only show items in the action bar relevant to this screen
            // if the drawer is not showing. Otherwise, let the drawer
            // decide what to show in the action bar.
            getMenuInflater().inflate(R.menu.troop_screen, menu);
            restoreActionBar();
            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        return id == R.id.action_settings || super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";
        private troopScreen troopScreen = new troopScreen();

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_troop_screen, container, false);
            assert rootView != null;

            //First Troop
            ImageView imageView = (ImageView) rootView.findViewById(R.id.t_first_troop);
            imageView.setImageResource(troopScreen.getFirstTroop(getArguments().getInt(ARG_SECTION_NUMBER)));

            //First Troop Text
            TextView textView = (TextView) rootView.findViewById(R.id.t_first_troop_text);
            textView.setText(troopScreen.getFirstTroopText(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Second Troop
            ImageView imageView1 = (ImageView) rootView.findViewById(R.id.t_second_troop);
            imageView1.setImageResource(troopScreen.getSecondTroop(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Second Troop Text
            TextView textView1 = (TextView) rootView.findViewById(R.id.t_second_troop_text);
            textView1.setText(troopScreen.getSecondTroopText(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Third Troop
            ImageView imageView2 = (ImageView) rootView.findViewById(R.id.t_third_troop);
            imageView2.setImageResource(troopScreen.getThirdTroop(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Third Troop Text
            TextView textView2 = (TextView) rootView.findViewById(R.id.t_third_troop_text);
            textView2.setText(troopScreen.getThirdTroopText(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Fourth Troop
            ImageView imageView3 = (ImageView) rootView.findViewById(R.id.t_fourth_troop);
            imageView3.setImageResource(troopScreen.getFourthTroop(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Fourth Troop Text
            TextView textView3 = (TextView) rootView.findViewById(R.id.t_fourth_troop_text);
            textView3.setText(troopScreen.getFourthTroopText(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Troop Description
            ImageView imageView4 = (ImageView) rootView.findViewById(R.id.t_description);
            imageView4.setImageResource(troopScreen.getDescription(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Troop Costs
            ImageView imageView5 = (ImageView) rootView.findViewById(R.id.t_stats);
            imageView5.setImageResource(troopScreen.getTroop_costs(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Troop Stats
            ImageView imageView6 = (ImageView) rootView.findViewById(R.id.t_second_stats);
            imageView6.setImageResource(troopScreen.getTroop_stats(getArguments().getInt(ARG_SECTION_NUMBER)));

            //More Troop Stats
            ImageView imageView7 = (ImageView) rootView.findViewById(R.id.t_third_stats);
            imageView7.setImageResource(troopScreen.getTroop_stats2(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Fifth Troop
            ImageView imageView8 = (ImageView) rootView.findViewById(R.id.t_fifth_troop);
            imageView8.setImageResource(troopScreen.getFifthTroop(getArguments().getInt(ARG_SECTION_NUMBER)));

            //Fifth Troop Text
            TextView textView4 = (TextView) rootView.findViewById(R.id.t_fifth_troop_text);
            textView4.setText(troopScreen.getFifthTroopText(getArguments().getInt(ARG_SECTION_NUMBER)));

            return rootView;
        }

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            ((troopScreen) activity).onSectionAttached(
                    getArguments().getInt(ARG_SECTION_NUMBER));
        }
    }
}

What could be possibly causing this?

Upvotes: 2

Views: 803

Answers (4)

Ben Pearson
Ben Pearson

Reputation: 7752

As the accepted answer suggests, looks like a circular reference causing a memory leak..

For anyone who hits similar errors, there's a great Google IO video that does in to a great detail on how to debug and get to the bottom of memory errors. This should give you the tools to get to the bottom of any memory leaks that can't be solved on SO.

Upvotes: 1

J Steven Perry
J Steven Perry

Reputation: 1751

Start with this line of code (and remove it):

   private troopScreen troopScreen = new troopScreen();

It looks like you need this in order to access the utility methods in the troopScreen class (which should be renamed to TroopScreen to follow standard Java naming conventions, and through the rest of this post that is how I will refer to it).

I recommend you make those methods static and call them via calls like TroopScreen.getFirstTroop() and so forth (or consider moving them to your Fragment, or possible an external class).

It looks like you may have a circular reference because you actually have an instance of an Activity (TroopScreen) inside your Fragment. I am no Fragment Manager expert, but I cannot imagine that is not causing some kind of problem should your Fragment need to be destroyed.

I suspect that is your memory leak.

Good luck.

Upvotes: 1

r-hold
r-hold

Reputation: 1120

OutOfMemory near decoding Bitmaps is typicaly due to lading to much images into the memory. Keep in mind: If a bitmap is loaded into mem it id decrompesses and consumes resolution x colorDepth bytes, which can be a lot for big images on higher density screens.

Also if you always releoad your images, but have a hidden memory leak you might run into problems. When dealing with a lot of images you should try to cache and reuse them. Try following the best practive described in this http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html tutorial.

Upvotes: 0

lakshman
lakshman

Reputation: 2741

run with -Xmx command line option

set VM arguments like this -Xmx1024M

Upvotes: 0

Related Questions