SplashScreen using PNG image leads to Android.Views.InflateException followed by OutOfMemory

可紊 提交于 2019-12-05 17:55:05

OK, I found a way to do this without throwing these errors.

Instead of creating a Layout with the Splash Screen, I created a theme, since in your case it is simply an image anyways:

styles.xml

<?xml version="1.0" encoding="utf-8" ?>
<resources>
  <style name="SplashTheme" parent="@android:style/Theme.NoTitleBar">
    <item name="android:background">@drawable/kitten</item>
  </style>
</resources>

Then I created an Activity like this:

using Android.App;
using Android.Content;
using Android.OS;

namespace SplashScreenSample
{
    [Activity(Label = "Splushy Splushy", MainLauncher = true, Theme = "@style/SplashTheme")]
    public class SplashActivity : Activity
    {
        protected override void OnCreate(Bundle b)
        {
            base.OnCreate(b);
            StartNextActivity();
        }

        private void StartNextActivity()
        {
            var intent = new Intent(this, typeof(SplashActivity));
            intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearWhenTaskReset);
            StartActivity(intent);
            Finish();
        }
    }
}

I tried running this on my phone for 10 minutes or so, without any crash with an image of 1600x1200 of a nice kitten.

ForceMagic

I found another solution that helped, but never as much as Cheesebaron's solution.

In both cases, it end up crashing.

  • Cheesebaron's solution crashes after : 14 minutes
  • Mine crashes after 3 minutes 28 sec.

Since I'm looping intensively to push the device to its limit, Cheesebaron's solution is surely viable.

In my case, instead of setting android:background="@drawable/splash", I removed that entry and used a private Bitmap field in my activity which I then load and pass it to the background drawable.

private Bitmap _bitmapRef;

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);        
    var view = FindViewById<LinearLayout>(Resource.Id.SplashScreenView);

    _bitmapRef = BitmapFactory.DecodeResource(Resources, Resource.Drawable.splash, new BitmapFactory.Options
                                                                      {
                                                                          InPurgeable = true,
                                                                          InInputShareable = true
                                                                      });
    view.SetBackgroundDrawable(new BitmapDrawable(Resources, _bitmapRef));
    StartNextActivity();
}

Then, on the OnDestroy call, I override it to explicitly recycle the bitmap.

protected override void OnDestroy()
{
   base.OnDestroy();

   if (null != _bitmapRef && !_bitmapRef.IsRecycled)
   {
        _bitmapRef.Recycle();
        _bitmapRef = null;
    }
}

It seems to me like if Android have problems when the Bitmap is created at the Activity level.

I have another activities in which I load bitmaps in a list object to display them on screen. The list object is at the Activity level and the bitmaps are inside the list.

In that case, the memory seems to be handled properly when I use the above solution. I don't even have to call recycle on the bitmaps inside the list.

But for the SplashScreen, that solution doesn't seems to be enough.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!