OutOfMemoryError
Version of AppIntro:
implementation 'com.github.apl-devs:appintro:v4.2.3'
Phone info: Samsung
- Model: SM-S327VL
- Orientation: Portrait
- RAM free: 209.15 MB
- Disk free: 4.17 GB
Operating system:
- Version: 6.0.1
- Orientation: Portrait
- Rooted: No
This line was emphasized indicating the cause of error:
com.github.paolorotolo.appintro.AppIntroBaseFragment.onCreateView (AppIntroBaseFragment.java:103)
Fatal Exception: java.lang.OutOfMemoryError
Failed to allocate a 23950092 byte allocation with 16777216 free bytes and 21MB until OOM com.github.paolorotolo.appintro.AppIntroBaseFragment.onCreateView
The complete Log:
android.graphics.BitmapFactory.nativeDecodeAsset (BitmapFactory.java)
android.graphics.BitmapFactory.decodeStream (BitmapFactory.java:856)
android.graphics.BitmapFactory.decodeResourceStream (BitmapFactory.java:675)
android.graphics.drawable.Drawable.createFromResourceStream (Drawable.java:2230)
android.content.res.Resources.loadDrawableForCookie (Resources.java:4282)
android.content.res.Resources.loadDrawable (Resources.java:4156)
android.content.res.Resources.getDrawable (Resources.java:2045)
android.content.res.Resources.getDrawable (Resources.java:2027)
android.content.Context.getDrawable (Context.java:464)
android.support.v4.content.ContextCompat.getDrawable (ContextCompat.java:358)
android.support.v7.widget.AppCompatDrawableManager.getDrawable (AppCompatDrawableManager.java:198)
android.support.v7.widget.AppCompatDrawableManager.getDrawable (AppCompatDrawableManager.java:186)
android.support.v7.content.res.AppCompatResources.getDrawable (AppCompatResources.java:100)
android.support.v7.widget.AppCompatImageHelper.setImageResource (AppCompatImageHelper.java:85)
android.support.v7.widget.AppCompatImageView.setImageResource (AppCompatImageView.java:93)
com.github.paolorotolo.appintro.AppIntroBaseFragment.onCreateView (AppIntroBaseFragment.java:103)
android.support.v4.app.Fragment.performCreateView (Fragment.java:2346)
android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1428)
android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState (FragmentManager.java:1759)
android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1827)
android.support.v4.app.BackStackRecord.executeOps (BackStackRecord.java:797)
android.support.v4.app.FragmentManagerImpl.executeOps (FragmentManager.java:2596)
android.support.v4.app.FragmentManagerImpl.executeOpsTogether (FragmentManager.java:2383)
android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute (FragmentManager.java:2338)
android.support.v4.app.FragmentManagerImpl.execSingleAction (FragmentManager.java:2215)
android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss (BackStackRecord.java:649)
android.support.v4.app.FragmentPagerAdapter.finishUpdate (FragmentPagerAdapter.java:145)
android.support.v4.view.ViewPager.populate (ViewPager.java:1238)
android.support.v4.view.ViewPager.populate (ViewPager.java:1086)
android.support.v4.view.ViewPager$3.run (ViewPager.java:267)
android.view.Choreographer$CallbackRecord.run (Choreographer.java:911)
android.view.Choreographer.doCallbacks (Choreographer.java:686)
android.view.Choreographer.doFrame (Choreographer.java:619)
android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:897)
android.os.Handler.handleCallback (Handler.java:739)
android.os.Handler.dispatchMessage (Handler.java:95)
android.os.Looper.loop (Looper.java:148)
android.app.ActivityThread.main (ActivityThread.java:7422)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1230)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1120)```
I use AppIntro in the most standard way:
SliderPage sliderPage1 = new SliderPage();
sliderPage1.setTitle("Welcome!");
sliderPage1.setDescription("Here's a quick intro.");
sliderPage1.setImageDrawable(R.drawable.icon1);
sliderPage1.setBgColor(Color.TRANSPARENT);
addSlide(AppIntroFragment.newInstance(sliderPage1));
addSlide(AppIntroFragment.newInstance("Welcome", "Enjoy", R.drawable.icon1, R.drawable.gradient));
Do you have a sample project or some code to share to reproduce this?
Yes. I gave a snippet of the code above, and here's the entire code (with some repetition of the snippet).
public class IntroActivity extends AppIntro {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// I added this try/catch block to avoid another OutOfMemoryError cras
try {
setDoneText("Log In");
setSkipText("Skip to Log In");
SliderPage sliderPage1 = new SliderPage();
sliderPage1.setTitle("Welcome!");
sliderPage1.setDescription("Here's a quick intro about FridgeMate.");
sliderPage1.setImageDrawable(R.drawable.icon1);
sliderPage1.setBgColor(Color.TRANSPARENT);
addSlide(AppIntroFragment.newInstance(sliderPage1));
SliderPage sliderPage2 = new SliderPage();
sliderPage2.setTitle("Content List");
sliderPage2.setDescription("Every thing in your fridge at a glance.");
sliderPage2.setImageDrawable(R.drawable.intro1);
sliderPage2.setBgColor(Color.TRANSPARENT);
addSlide(AppIntroFragment.newInstance(sliderPage2));
SliderPage sliderPage3 = new SliderPage();
sliderPage3.setTitle("Put stuff in your fridge");
sliderPage3.setDescription("Simply by clicking the + Button.\n Try Quick Add, it scans! \n");
sliderPage3.setImageDrawable(R.drawable.intro2);
sliderPage3.setBgColor(Color.TRANSPARENT);
addSlide(AppIntroFragment.newInstance(sliderPage3));
SliderPage sliderPage4 = new SliderPage();
sliderPage4.setTitle("Need cooking advice? \nSure!");
sliderPage4.setDescription("FridgeMate recommends you recipes based on what you have in your fridge");
sliderPage4.setImageDrawable(R.drawable.intro3);
sliderPage4.setBgColor(Color.TRANSPARENT);
addSlide(AppIntroFragment.newInstance(sliderPage4));
SliderPage sliderPage5 = new SliderPage();
sliderPage5.setTitleTypeface("casual");
sliderPage5.setTitle("Fridge? Friends?");
sliderPage5.setDescription("Invite friends to your \"fridge family\". \n Connect with people and their foods.");
sliderPage5.setImageDrawable(R.drawable.intro4);
sliderPage5.setBgColor(Color.TRANSPARENT);
addSlide(AppIntroFragment.newInstance(sliderPage5));
SliderPage sliderPage6 = new SliderPage();
sliderPage6.setTitleTypeface("casual");
sliderPage6.setTitle("Need a reminder about what to buy?");
sliderPage6.setDescription("Of course, here's your shopping list.");
sliderPage6.setImageDrawable(R.drawable.intro5);
sliderPage6.setBgColor(Color.TRANSPARENT);
addSlide(AppIntroFragment.newInstance(sliderPage6));
// Instead of fragments, you can also use our default slide
// Just set a title, description, background and image. AppIntro will do the rest.
addSlide(AppIntroFragment.newInstance("Welcome to FridgeMate.", "Enjoy! - C.O.O.L", R.drawable.icon1, R.drawable.animation_gradient));
// Hide Skip/Done button.
showSkipButton(true);
setProgressButtonEnabled(true);
}
catch(OutOfMemoryError e){
Intent i = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(i);
setResult(CLOSE_ALL);
finish();
return;
}
}
final int CLOSE_ALL = 23333;
@Override
public void onSkipPressed(Fragment currentFragment) {
super.onSkipPressed(currentFragment);
Intent i = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(i);
setResult(CLOSE_ALL);
finish();
}
@Override
public void onDonePressed(Fragment currentFragment) {
super.onDonePressed(currentFragment);
Intent i = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(i);
setResult(CLOSE_ALL);
finish();
}
@Override
public void onSlideChanged(@Nullable Fragment oldFragment, @Nullable Fragment newFragment) {
super.onSlideChanged(oldFragment, newFragment);
}
}
was this issue resolved?
No, the issue wasn't solved. I'm sorry for mis-pressing the Close button. In addition, with the exact same code I provided above, it has led many same crashes happened on Asus (Zenfone), Samsung(Galaxy S5, Galaxy J3), Huawei (P9 lite), LGE (Nexus), and two other brands. Let me know if there's more info I can find to help you resolve it!
Hey @YoiYang
Looks like the problem is with the assets you're using. The app is trying to allocate 23Mb, so can I ask you to check the size of:
R.drawable.intro1
R.drawable.intro2
R.drawable.intro3
R.drawable.intro4
R.drawable.icon1
R.drawable.animation_gradient
Furthermore, if you could provide a branch/fork would be better for debugging/profiling.
As I double checked the sizes of these files, they sum up to less than 400kb. For the recent versions of my app, I didn't use R.drawable.animation_gradient. But errors continue to occur on different Android phone platforms (LGE, LYF, Prestigio, Xiaomi, Samsung) from Android 4 to Android 7.
Here's a hyperlink to the file where I use the AppIntro: https://github.com/htoo97/FridgeMate-mobile/blob/master/app/src/main/java/com/fridgemate/yangliu/fridgemate/IntroActivity.java
As a sidenote, my app's compiled and target sdk version is 27; its minimum sdk version is 21.
This is a known issue for devices with lower resolutions. You should scale down your images so the device doesn't have to do it at runtime. See here for more: https://github.com/paolorotolo/AppIntro/issues/402#issuecomment-439701856
Hey @paolorotolo Do you think using fragmentpageradapter/fragmentstatepageradapter in appintrobase could potentially solve this issue(From what I read, one destroys the view hierarchy and another destroys the whole fragment if not in view that could potentially save memory)