Android - Prevent white screen at startup

2019-01-10 00:14发布

As we all know, many Android apps display a white screen very briefly before their first Activity comes into focus. This problem is observed in the following cases:

  • Android apps that extend the global Application class and perform major initializations therein. The Application object is always created before the first Activity (a fact that can be observed in the debugger), so this makes sense. This is the cause of the delay in my case.

  • Android apps that display the default preview window before the splash screen.

Setting android:windowDisablePreview = "true" obviously does not work here. Nor can I set the parent theme of the splash screen to Theme.Holo.NoActionBar as described here, because [unfortunately] my splash screen makes use of an ActionBar.

Meanwhile, apps that do not extend the Application class do not show the white screen at startup.

The thing is, ideally the initializations performed in the Application object need to occur before the first Activity is shown. So my question is, how can I perform these initializations on app startup without using an Application object? Possibly using a Thread or Service, I suppose?

This is an interesting problem to think about. I can't bypass it the usual way (by setting the NoActionBar theme), as tragically my Splash screen actually has an ActionBar due to some unrelated reasons.

Note:

I have already referred to the following questions:

References:

14条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-10 01:04

Please copy and paste these two lines in your manifest app theme i.e res/styles/AppTheme. then it will work like charm..

<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>
查看更多
【Aperson】
3楼-- · 2019-01-10 01:05

I had same issue, you have to update your style.

style.xml

<!-- Base application theme. -->
 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

        <!-- Customize your theme here. -->
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowDisablePreview">true</item>
        <item name="android:windowBackground">@null</item>
        <item name="android:windowIsTranslucent">true</item>

 </style>

Your manifest file should looks like below.

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
     // Other stuff
</application>

Outout:

enter image description here

Hope this would help you.

查看更多
祖国的老花朵
4楼-- · 2019-01-10 01:07

I would recommend taking a look at the answer given at this page. Solved using the Style property. It does not bother the user.

查看更多
Juvenile、少年°
5楼-- · 2019-01-10 01:08

Have you tried setting theandroid:windowBackground attribute in the theme of your launcher activity, to either a color or a drawable?

For example this:

<item name="android:windowBackground">@android:color/black</item>

when added to the Launcher activity theme will show a black color (rather than the white color) on startup. This is an easy trick to hide long initialisation, while showing your users something, and it works fine even if you subclass the Application object.

Avoid using other constructs (even Threads) for doing long initialisation tasks, because you may end up not being able to control the lifecycle of such constructs. The Application object is the correct place for doing exactly this type of actions.

查看更多
做自己的国王
6楼-- · 2019-01-10 01:09

Did you try to put initialization to onActivityCreated?

Inside Application class :

 registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                if(activity.getClass().equals(FirstActivity.class) {
                    // try without runOnUiThread if it will not help
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            new InitializatioTask().execute();
                        }
                    });
                }
            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
查看更多
贼婆χ
7楼-- · 2019-01-10 01:12

Recommended way of solving this problem is missing in the answers. So I am adding my answer here. The white-screen-at-startup problem occurs because of the initial blank screen that the system process draws when launching the app. A common way to solve this is by turning off this initial screen by adding this to your styles.xml file.

<item name="android:windowDisablePreview">true</item>

But according to android documentation this can result in longer startup time. Recommended way of avoiding this initial white screen according to google is to use activity's windowBackground theme attribute and provide a simple custom drawable for the starting activity.

Like this:

Drawable Layout file, my_drawable.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
  <!-- The background color, preferably the same as your normal theme -->
  <item android:drawable="@android:color/white"/>
  <!-- Your product logo - 144dp color version of your app icon -->
  <item>
    <bitmap
      android:src="@drawable/product_logo_144dp"
      android:gravity="center"/>
  </item>
</layer-list>

Create a new style in your styles.xml

<!-- Base application theme. -->
<style name="AppTheme">
    <!-- Customize your theme here. -->               
</style>

<!-- Starting activity theme -->
<style name="AppTheme.Launcher">
    <item name="android:windowBackground">@drawable/my_drawable</item>
</style>

Add this theme to your starting activity in the Manifest file

<activity ...
android:theme="@style/AppTheme.Launcher" />

And when you want to transition back to your normal theme call setTheme(R.style.Apptheme) before calling super.onCreate() and setContentView()

public class MainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    // Make sure this is before calling super.onCreate
    setTheme(R.style.Theme_MyApp);
    super.onCreate(savedInstanceState);
    // ...
  }
}

This is the recommended way to solve the problem and this is from google Material Design patterns.

查看更多
登录 后发表回答