0

I decided to create a splashscreen at the beginning of my app. I created a 1600x900 image and used it as a drawable. When I ran my app, it seemed like every action bears a 1 second delay. After checking everything I realized that it was the splashscreen somehow causing this lag. Tests reveal that high resolution images made into drawables this way cause delays, I don't know why.

My image weighs 100kb, I gradually lowered the resolution and the size and the lag gradually lowered as well. I also made a high resolution, 5kb image and the lag persisted, meaning that the resolution is mostly the culprit.

Why is this happening and how can I have a splashscreen without later repercussions?

code:

in styles:

<style name="splashscreenTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="android:windowBackground">@drawable/splashscreen</item>
    </style>

in manifest:

    <application
        android:allowBackup="true"
        android:icon="@drawable/logo"
        android:label="@string/app_name"
        android:fullBackupContent="false"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:label="@string/app_name"
            android:theme="@style/splashscreenTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>
daedsidog
  • 1,732
  • 2
  • 17
  • 36
  • What device are you seeing this behaviour on? – adelphus Feb 09 '16 at 22:15
  • 1
    You should use `Glide` library and load the image resource into your `ImageView` using Glide `Glide.with(container.getContext()).load(R.drawable.splashscreen).crossFade().into(imageView);` – EpicPandaForce Feb 10 '16 at 08:49

1 Answers1

2

The lag you are experiencing is probably due to Garbage Collection or Heap size increase.

Your image is 1600*900 = 1440000px. Each pixel is has an in-memory size of four byte - one per color (RGB) and one for transparency (A). We can therefore calculate: 1440000 * 4B = 5760000B so around 5.7 MB allocated on the heap for the byte-array alone. But it's a drawable, and has some more fields than the byte-array, so you end up with a little more.

Add Activities, Strings, other images and resources and it's much higher.

Now, whenever you create a new object the VM tries to delete some unused objects (Garbage collection) causing a small lag. If it cannot free enough memory the Heap will increase (also causing a small lag).

You are probably facing one of these issues, so what can you do about it?

You didn't write it, but I assume that the splash screen is not the only Activity of your App. The problem is that the splash screen stays active in the background. You can't really do anything about that, but you can at least remove the drawable manually.

View window = getWindow().getDecorView();
if (window.getBackground() != null) {
    window.getBackground().setCallback(null);
    window.setBackground(null);
}

In general, it's a better idea to not use large images in xml attributes. It's much more memory efficient to create the bitmap yourself in size you really need (not all devices have a 1600*900 resolution).

Android gives you the BitmapFactory class to do this. Check out Pre-scaling Bitmaps and Most memory efficient way to resize bitmaps on android? for more info on the whole topic.

Community
  • 1
  • 1
Lovis
  • 9,513
  • 5
  • 31
  • 47
  • While I'm not sure about your size calculations (my image is a compressed jpg (perhaps you are talking about how Android saves them regardless?)) setting the background to null does fix it. Thank you very much! – daedsidog Feb 10 '16 at 08:52
  • @JohanZ. yes, the compression doesn't matter. it's just the pixels. one pixel in ARGB is 4 byte. you can't do anything about it. – Lovis Feb 10 '16 at 09:27