web-dev-qa-db-fra.com

Android - Empêcher l'écran blanc au démarrage

Comme nous le savons tous, de nombreuses applications Android affichent un écran blanc très brièvement avant que leur première Activity ne devienne nette. Ce problème est observé dans les cas suivants:

  • Les applications Android qui étendent la classe globale Application class et Y effectuent des initialisations majeures. L'objet Application Est toujours créé avant la première Activity (un fait qui peut être observé dans le débogueur), cela a donc un sens. C'est la cause du retard dans mon cas.

  • Applications Android qui affichent la fenêtre de prévisualisation par défaut avant l'écran de démarrage.

Régler Android:windowDisablePreview = "true" ne fonctionne évidemment pas ici. Je ne peux pas non plus définir le thème parent de l'écran de démarrage sur Theme.Holo.NoActionBar comme décrit ici , car [malheureusement] mon écran de démarrage utilise une variable ActionBar.

Pendant ce temps, les applications qui ne prolongent pas la Application classe ne le pas affichent un écran blanc au démarrage.

En réalité, idéalement, les initialisations effectuées dans l'objet Application doivent se produire avant la première Activity est affichée. Ma question est donc la suivante: comment puis-je effectuer ces initialisations au démarrage de l'application sans à l'aide d'un objet Application? Peut-être en utilisant Thread ou Service, je suppose?

C'est un problème intéressant à considérer. Je ne peux pas le contourner de la manière habituelle (en définissant le thème NoActionBar), car, tragiquement, mon écran Splash a en fait une ActionBar pour une raison quelconque.

Remarque:

J'ai déjà évoqué les questions suivantes:

Références:

66
Y.S.

Le problème de fond blanc est dû au démarrage à froid d'Android pendant le chargement de l'application en mémoire, ce qui permet d'éviter ce problème:

public class OnboardingWithCenterAnimationActivity extends AppCompatActivity {
public static final int STARTUP_DELAY = 300;
public static final int ANIM_ITEM_DURATION = 1000;
public static final int ITEM_DELAY = 300;

private boolean animationStarted = false;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    setTheme(R.style.AppTheme);
    getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_onboarding_center);
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {

    if (!hasFocus || animationStarted) {
        return;
    }

    animate();

    super.onWindowFocusChanged(hasFocus);
}

private void animate() {
    ImageView logoImageView = (ImageView) findViewById(R.id.img_logo);
    ViewGroup container = (ViewGroup) findViewById(R.id.container);

    ViewCompat.animate(logoImageView)
        .translationY(-250)
        .setStartDelay(STARTUP_DELAY)
        .setDuration(ANIM_ITEM_DURATION).setInterpolator(
            new DecelerateInterpolator(1.2f)).start();

    for (int i = 0; i < container.getChildCount(); i++) {
        View v = container.getChildAt(i);
        ViewPropertyAnimatorCompat viewAnimator;

        if (!(v instanceof Button)) {
            viewAnimator = ViewCompat.animate(v)
                    .translationY(50).alpha(1)
                    .setStartDelay((ITEM_DELAY * i) + 500)
                    .setDuration(1000);
        } else {
            viewAnimator = ViewCompat.animate(v)
                    .scaleY(1).scaleX(1)
                    .setStartDelay((ITEM_DELAY * i) + 500)
                    .setDuration(500);
        }

        viewAnimator.setInterpolator(new DecelerateInterpolator()).start();
    }
}
}

disposition

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="?colorPrimary"
Android:orientation="vertical"
>

<LinearLayout
    Android:id="@+id/container"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center"
    Android:gravity="center"
    Android:orientation="vertical"
    Android:paddingTop="144dp"
    tools:ignore="HardcodedText"
    >

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="center_horizontal"
        Android:layout_marginTop="16dp"
        Android:alpha="0"
        Android:text="Hello world"         Android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
        Android:textColor="@Android:color/white"
        Android:textSize="22sp"
        tools:alpha="1"
        />

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="center_horizontal"
        Android:layout_marginTop="8dp"
        Android:alpha="0"
        Android:gravity="center"
        Android:text="This a Nice text"
      Android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle.Inverse"
        Android:textSize="20sp"
        tools:alpha="1"
        />

    <Button
        Android:id="@+id/btn_choice1"
        Android:layout_width="200dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="48dp"
        Android:scaleX="0"
        Android:scaleY="0"
        Android:text="A Nice choice"
        Android:theme="@style/Button"
        />

    <Button
        Android:id="@+id/btn_choice2"
        Android:layout_width="200dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="4dp"
        Android:scaleX="0"
        Android:scaleY="0"
        Android:text="Far better!"
        Android:theme="@style/Button"
        />

</LinearLayout>

<ImageView
    Android:id="@+id/img_logo"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center"
    Android:src="@drawable/img_face"
    tools:visibility="gone"
    />
</FrameLayout>

img face

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:opacity="opaque">

<item Android:drawable="?colorPrimary"/>
<item>
    <bitmap
        Android:gravity="center"
        Android:src="@drawable/img_face"/>
</item>

Ajouter ce thème à votre écran de démarrage dans le manifeste

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="Android:windowBackground">@null</item>
</style>

<style name="AppTheme.CenterAnimation">
    <item name="Android:windowBackground">@drawable/ll_face_logo</item>
</style>

qui produira un effet comme celui-ci

a busy cat

pour plus de détails et plus de solutions, vous pouvez vérifier ceci BlogPost

55

s'il vous plaît ajouter cette ligne dans le thème de votre application 

<item name="Android:windowDisablePreview">true</item>
40
Hitesh Singh

Tout d'abord, pour supprimer l'écran blanc, lisez ceci - https://www.bignerdranch.com/blog/splash-screens-the-right-way/

Mais plus important encore, optimisez votre charge initiale et ajustez tout travail lourd au moment où vous avez le temps de l’exécuter. Postez votre classe d'application ici si vous souhaitez que nous l'examinions.

17
Shmuel

Veuillez copier et coller ces deux lignes dans le thème de votre application manifeste, à savoir res/styles/AppTheme. alors cela fonctionnera comme un charme ..

<item name="Android:windowDisablePreview">true</item>
<item name="Android:windowIsTranslucent">true</item>
11
prasad reddy

Avez-vous essayé de définir l'attributAndroid:windowBackground dans le thème de votre activité de lancement, sur une couleur ou sur un dessin?

Par exemple ceci: 

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

une fois ajouté au thème d'activité Launcher, il affichera une couleur noire (plutôt que la couleur blanche) au démarrage. C'est une astuce facile pour masquer une longue initialisation, tout en montrant quelque chose à vos utilisateurs, et cela fonctionne bien même si vous sous-classez l'objet Application.

Évitez d’utiliser d’autres constructions (même Threads) pour effectuer de longues tâches d’initialisation, car vous risqueriez de ne pas pouvoir contrôler le cycle de vie de ces constructions. L'objet Application est l'endroit approprié pour effectuer exactement ce type d'actions. 

7
George Metaxas

J'ai eu le même problème, vous devez mettre à jour votre 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>

Votre fichier manifeste devrait ressembler à celui ci-dessous.

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

Dehors:

 enter image description here

J'espère que cela vous aiderait.

6
Hiren Patel

Dans les méthodes de rappel du cycle de vie, vous pouvez déclarer le comportement de votre activité lorsque l'utilisateur la quitte et y revient. Rappelez-vous que la façon dont Android est conçu, il existe un cycle de vie pour chaque application. Si vous chargez trop la méthode onCreate() (c'est-à-dire la méthode utilisée pour charger les fichiers de présentation et initaliser tous les contrôles que vous y avez), l'écran blanc deviendra plus visible car le chargement du fichier de présentation prendra plus longtemps.

Je suggère d'utiliser plusieurs méthodes différentes au début d'une activité. Tels sont le onStart() (appelé dès que l'application est chargée), onActivityCreated() (appelé après l'affichage de la mise en page et utile si vous effectuez un traitement de données au démarrage de l'activité).

Pour vous faciliter la tâche, voici le diagramme officiel du cycle de vie des activités:

 enter image description here

6
Michele La Ferla

Avez-vous essayé de mettre l'initialisation à onActivityCreated?

Dans la classe Application:

 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) {

            }
        });
2
Sergey Shustikov

Comme vous le savez déjà, cet écran blanc est présent, en raison de processus en arrière-plan, d'initialisation d'applications ou de fichiers volumineux, il vous suffit donc de vérifier ci-dessous l'idée de surmonter cette idée.

Pour éviter cet écran blanc au début de l'application, un moyen est l'écran de démarrage, il s'agit simplement d'un moyen non final et vous devez utiliser.

Lorsque vous montrez un écran de démarrage à partir de votre fichier splash.xml, le problème reste le même,

Vous devez donc créer un style dans un fichier style.xml pour l’écran d’accueil et y définir l’arrière-plan de la fenêtre comme image d’accueil, puis appliquer ce thème à votre activité d’éclairement à partir du fichier manifeste. Alors maintenant, lorsque vous exécuterez l'application, tout d'abord, il va définir le thème et ainsi, l'utilisateur sera en mesure de voir directement l'image de démarrage au lieu de l'écran blanc.

2
Vickyexpert

La méthode recommandée pour résoudre ce problème manque dans les réponses. J'ajoute donc ma réponse ici. Le problème de l'écran blanc au démarrage est dû au premier écran vide dessiné par le processus système lors du lancement de l'application. Un moyen courant de résoudre ce problème consiste à désactiver cet écran initial en l'ajoutant à votre fichier styles.xml.

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

Mais selon la documentation Android, cela peut entraîner un temps de démarrage plus long. La méthode recommandée pour éviter cet écran blanc initial selon Google consiste à utiliser l'attribut de thème windowBackground de l'activité et à fournir un dessin personnalisable simple pour l'activité de départ. 

Comme ça:

Fichier de mise en page pouvant être dessiné, 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>

Créez un nouveau style dans votre 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>

Ajouter ce thème à votre activité de départ dans le fichier manifeste 

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

Et lorsque vous souhaitez revenir à votre thème habituel, appelez setTheme(R.style.Apptheme) avant d'appeler super.onCreate() et 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);
    // ...
  }
}

C’est la méthode recommandée pour résoudre le problème, à partir de Google Material Design patterns.

2
Sam

Les deux propriétés fonctionnent

    <style name="AppBaseThemeDark" parent="@style/Theme.AppCompat">
            <!--your other properties -->
            <!--<item name="Android:windowDisablePreview">true</item>-->
            <item name="Android:windowBackground">@null</item>
            <!--your other properties -->
    </style>
2
Sohail Zahid

J'ai ajouté les deux lignes suivantes dans mon thème Sous styles.xml

    <item name="Android:windowDisablePreview">true</item>
    <item name="Android:windowBackground">@null</item>

Travaillé comme un charme

0
Akanshi Srivastava

Il suffit d'écrire l'élément dans values ​​/ styles.xml:

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

Par exemple, dans AppTheme:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="Android:windowFullscreen">true</item>
    <item name="Android:windowContentOverlay">@null</item>

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

    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>
0
Javier Reinoso
Style :- 
<style name="SplashViewTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="Android:windowBackground">@drawable/splash</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

In Manifest :- 
<activity Android:name=".SplashActivity"
        Android:theme="@style/SplashViewTheme">
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
0
Krishna

S'il vous plaît essayez cela une fois.

1) Créez un fichier dessinable splash_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:drawable="@color/{your color}" />

    <item>
        <bitmap
            Android:layout_width="@dimen/size_250"
            Android:layout_height="@dimen/size_100"
            Android:gravity="center"
            Android:scaleType="fitXY"
            Android:src="{your image}"
            Android:tint="@color/colorPrimary" />
    </item>

</layer-list>

2) Mettez ceci dans styles.xml

     <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
         <item name="Android:windowBackground">@drawable/background_splash</item>
     </style>

3) Dans votre AndroidMainfest.xml, définissez le thème ci-dessus sur Activité de lancement.

       <activity
            Android:name=".SplashScreenActivity"
            Android:screenOrientation="portrait"
            Android:theme="@style/SplashTheme"
            Android:windowSoftInputMode="stateVisible|adjustResize">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />

                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
0
Surendar D