1

I'm new to android and making a picture app but I'm having a problem where I'm running out of memory.

The main activity is a grid of buttons that start new activities which have a view pager photo slider, showing 5ish photos. It's currently workings but after returning to the main screen and selecting a new button, which starts a new photo activity, it becomes slow than crashes.

After watching the monitors, memory is allocated every time an activity starts but when the back button is pressed the memory is not deallocated.

I know people have suggested using the glide library but I'm running 5 small size photos for each activity and if the memory can be deallocated when the activity is no longer needed then my current set up should work.

I know the way I'm doing this is not the best way but I'm just trying to get it working quickly, then I can go back and optimize it.

Where is the memory leak or my error?

Advice?

Thanks in advance.

public class MainActivity extends AppCompatActivity {

static int picSet = 1; //the set of pictures i want

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void startActiv()
{
    startActivity(new Intent(MainActivity.this, PagerSetUp.class));
}

//Button/Image
public void firstMet(View view) {
    picSet = 1;
    startActiv();
}
//Button/Image
public void wedding (View view) {
    picSet = 2;
    startActiv();
}
//Button/Image
public void vacation(View view) {
    picSet = 3;
    startActiv();
}
//Button/Image
public void pups (View view) {
    picSet = 4;
    startActiv();
}
//Button/Image
public void ourHomes(View view) {
    picSet = 5;
    startActiv();
}
//Button/Image
public void age (View view) {
    picSet = 6;
    startActiv();
}
//Button/Image
public void family(View view) {
    picSet = 7;
    startActiv();
}
//Button/Image
public void friends (View view) {
    picSet = 8;
    startActiv();
}
}

public class PagerSetUp extends AppCompatActivity {

//Create an instance of the pager adapter class
CustomPagerAdapter mCustomPagerAdapter; //Creates content for each page

//Create an instance of the view pager class
ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.collections_main); //XML File

    //Setting up the ViewPager
    mCustomPagerAdapter = new CustomPagerAdapter(this);

    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mCustomPagerAdapter);
}
}

public class CustomPagerAdapter extends PagerAdapter {

public int[] firstMetPics = {
        R.drawable.fm1,
        R.drawable.fm2,
        R.drawable.fm3,
        R.drawable.fm4,
        R.drawable.fm5
};

public int[] weddingPics = {
        R.drawable.w1,
        R.drawable.w2,
        R.drawable.w3,
        R.drawable.w4,
        R.drawable.w5
};

public int[] vacationPics = {
        R.drawable.fm1,
        R.drawable.fm2,
        R.drawable.fm3,
        R.drawable.fm4,
        R.drawable.fm5
};

public int[] pupsPics = {
        R.drawable.fm1,
        R.drawable.fm2,
        R.drawable.fm3,
        R.drawable.fm4,
        R.drawable.fm5
};

public int[] homesPics = {
        R.drawable.fm1,
        R.drawable.fm2,
        R.drawable.fm3,
        R.drawable.fm4,
        R.drawable.fm5
};

public int[] agePics = {
        R.drawable.fm1,
        R.drawable.fm2,
        R.drawable.fm3,
        R.drawable.fm4,
        R.drawable.fm5
};

public int[] familyPics = {
        R.drawable.fm1,
        R.drawable.fm2,
        R.drawable.fm3,
        R.drawable.fm4,
        R.drawable.fm5
};

public int[] friendsPics = {
        R.drawable.fm1,
        R.drawable.fm2,
        R.drawable.fm3,
        R.drawable.fm4,
        R.drawable.fm5
};

protected Context mContext;
LayoutInflater mLayoutInflater;

public CustomPagerAdapter(Context context) {

    mContext = context;
    mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

//Specifies how many views to show in the ViewPager
@Override
public int getCount() {

    int picArrayLength = 0;

    switch (MainActivity.picSet) {
        case 1: picArrayLength = firstMetPics.length;
                break;
        case 2: picArrayLength = weddingPics.length;
                break;
        case 3: picArrayLength = vacationPics.length;
                break;
        case 4: picArrayLength = pupsPics.length;
                break;
        case 5: picArrayLength = homesPics.length;
                break;
        case 6: picArrayLength = agePics.length;
                break;
        case 7: picArrayLength = familyPics.length;
                break;
        case 8: picArrayLength = friendsPics.length;
                break;
        default: picArrayLength = firstMetPics.length;
                 break;
    }
    return picArrayLength;
}

@Override
public boolean isViewFromObject(View view, Object object) {
    return view ==(object);
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    View itemView = mLayoutInflater.inflate(R.layout.pager_item, container, false);

    ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);

    switch (MainActivity.picSet) {
        case 1: imageView.setImageResource(firstMetPics[position]);
                break;
        case 2: imageView.setImageResource(weddingPics[position]);
                break;
        case 3: imageView.setImageResource(vacationPics[position]);
                break;
        case 4: imageView.setImageResource(pupsPics[position]);
                break;
        case 5: imageView.setImageResource(homesPics[position]);
                break;
        case 6: imageView.setImageResource(agePics[position]);
                break;
        case 7: imageView.setImageResource(familyPics[position]);
                break;
        case 8: imageView.setImageResource(friendsPics[position]);
                break;
        default: imageView.setImageResource(firstMetPics[position]);
                break;
    }
    container.addView(itemView);

    return itemView;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((LinearLayout) object);
    Log.i("NOTE", "destroyed view");
}
J Walker
  • 23
  • 4
  • First of all you shouldn't use static objects like that. Static objects are the primary source of memory leak. You should adopt static objects only if it's really necessary. – Aldrin Joe Mathew Apr 25 '17 at 04:28
  • Use FragmentStatePagerAdapter with ViewPager, to avoid Out Of Memory problem, and also use Glide to load images – Faruk Apr 25 '17 at 04:53
  • Better go for free powerful library like Glide . Tutorial http://www.androidhive.info/2016/04/android-glide-image-library-building-image-gallery-app/ – Sreehari Apr 25 '17 at 05:08
  • check this link you can get better idea http://stackoverflow.com/questions/477572/strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object – Jignesh Jain Apr 25 '17 at 05:08
  • Thanks for the advice, I will look into glide and fragmentstatepageradapter. – J Walker Apr 25 '17 at 12:52

1 Answers1

0

OutOfMemory issue comes due to several issue. For your case i am guess its because of size of the images and number of the images. You can remove this issue by doing following things.

  • if these drawables are icons? Use vector drawables instead of normal png.
  • Compress images before adding to drawable folder.
  • Convert your png or jpg images to webP format. As Android giving support to webP now WebP. It will dramatically reduce your image size.
  • And most importantly don't set image drawable by using normal setImageDrawable or any method. Use Image loading libraries like Picasso, Glide, Fresco etc to load image drawable to ImageView. It will surely avoid outOfMemory issue.

Hope this will help you overcoming your problem. If you still have problem, do let me know. :)

Hammad Akram
  • 573
  • 3
  • 9