Reputation: 1715
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
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
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
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
Reputation: 2741
run with -Xmx
command line option
set VM arguments like this -Xmx1024M
Upvotes: 0