it-swarm.com.de

Android - Verhindert, dass beim Start ein weißer Bildschirm angezeigt wird

Wie wir alle wissen, zeigen viele Android-Apps sehr kurz einen weißen Bildschirm an, bevor ihre erste Activity in den Fokus gerät. Dieses Problem wird in den folgenden Fällen beobachtet:

  • Android-Apps, die die globale Klasse Application erweitern und wichtige Initialisierungen ausführen. Das Objekt Application wird immer vor der ersten Activity erstellt (eine Tatsache, die im Debugger beobachtet werden kann). Dies ist also sinnvoll. Dies ist die Ursache für die Verzögerung in meinem Fall.

  • Android-Apps, die das Standard-Vorschaufenster vor dem Begrüßungsbildschirm anzeigen.

Das Setzen von Android:windowDisablePreview = "true" funktioniert hier offensichtlich nicht. Ich kann das übergeordnete Design des Begrüßungsbildschirms auch nicht auf Theme.Holo.NoActionBar setzen, wie in hier beschrieben, da mein Begrüßungsbildschirm (leider) eine ActionBar verwendet.

In der Zwischenzeit zeigen Apps, die die Klasse Application nicht erweitern, beim Start den weißen Bildschirm an.

Die Sache ist, im Idealfall müssen die Initialisierungen, die im Objekt Application durchgeführt werden, stattfinden bevor die erste Activity angezeigt wird. Meine Frage ist also, wie kann ich diese Initialisierungen beim Start der App durchführen ohne mit einem Application-Objekt? Möglicherweise eine Thread oder Service, nehme ich an?

Dies ist ein interessantes Problem, über das man nachdenken sollte. Ich kann es nicht auf die übliche Weise umgehen (indem ich das Thema NoActionBar einstelle), da mein Begrüßungsbildschirm aus irgendeinem Grund tatsächlich eine ActionBar enthält.

Hinweis:

Ich habe bereits auf folgende Fragen hingewiesen:

Referenzen:

76
AndroidCarina

Das Problem mit weißem Hintergrund wird durch den Kaltstart von Android verursacht, während die App in den Speicher geladen wird, und es kann folgendermaßen vermieden werden:

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();
    }
}
}

layout

<?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 Gesicht

<?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>

Fügen Sie dieses Thema zu Ihrem Begrüßungsbildschirm im Manifest hinzu

<?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>

das wird efekt so produzieren

a busy cat

weitere Informationen und Lösungen finden Sie hier BlogPost

55

bitte fügen Sie diese Zeile in Ihr App-Design ein 

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

Um den weißen Bildschirm zu entfernen, lesen Sie zunächst Folgendes - https://www.bignerdranch.com/blog/splash-screens-the-right-way/

Wichtiger ist jedoch, dass Sie Ihre Anfangslast optimieren und schwere Arbeit auf den Zeitpunkt verschieben, zu dem Sie Zeit haben, um sie auszuführen. Stellen Sie Ihre Bewerbungsstunde hier ein, wenn Sie einen Blick darauf werfen möchten.

17
Shmuel

Bitte kopieren Sie diese beiden Zeilen und fügen Sie sie in Ihr Manifest-App-Theme ein, d. dann wird es wie charmant funktionieren ..

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

Haben Sie versucht, dasAndroid:windowBackground-Attribut im Thema Ihrer Starteraktivität auf eine Farbe oder eine Zeichnung zu setzen?

Zum Beispiel das: 

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

wenn sie zum Launcher-Aktivitätsdesign hinzugefügt wird, wird beim Start eine schwarze (und nicht weiße) Farbe angezeigt. Dies ist ein einfacher Trick, um die lange Initialisierung zu verbergen, während den Benutzern etwas angezeigt wird, und es funktioniert einwandfrei selbst wenn Sie das Application-Objekt subclassieren.

Vermeiden Sie die Verwendung anderer Konstrukte (auch Threads) für lange Initialisierungsaufgaben, da Sie möglicherweise nicht den Lebenszyklus solcher Konstrukte steuern können. Das Anwendungsobjekt ist der richtige Ort, um genau diese Art von Aktionen auszuführen. 

7
George Metaxas

Ich hatte das gleiche Problem, Sie müssen Ihren Stil aktualisieren.

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>

Ihre Manifestdatei sollte wie folgt aussehen.

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

Raus:

 enter image description here

Hoffe das würde dir helfen.

6
Hiren Patel

Innerhalb der Lifecycle-Callback-Methoden können Sie festlegen, wie sich Ihre Aktivität verhält, wenn der Benutzer die Aktivität verlässt und erneut eingibt. Denken Sie daran, dass Android so konzipiert ist, dass für jede App ein Lebenszyklus besteht. Wenn Sie die onCreate()-Methode (die Methode zum Laden der Layoutdateien und zur Initialisierung aller darin enthaltenen Steuerelemente) zu stark beansprucht, wird der weiße Bildschirm besser sichtbar, da das Laden der Layoutdatei länger dauert.

Ich empfehle, verschiedene Methoden zu verwenden, wenn Sie eine Aktivität beginnen. Dies sind onStart() (wird als erstes aufgerufen, wenn die App geladen wird), onActivityCreated() (wird aufgerufen, nachdem das Layout angezeigt wurde. Dies ist nützlich, wenn Sie beim Starten der Aktivität Daten verarbeiten.).

Um es Ihnen einfacher zu machen, finden Sie unten das offizielle Aktivitätslebenszyklusdiagramm:

 enter image description here

6

Haben Sie versucht, die Initialisierung in onActivityCreated zu setzen?

Innerhalb der Application-Klasse:

 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

Da Sie bereits wissen, warum dieser weiße Bildschirm vorhanden ist, beispielsweise aufgrund von Hintergrundprozessen oder der Initialisierung von Anwendungen oder wegen großer Dateien, überprüfen Sie die unten stehende Idee.

Um diesen weißen Bildschirm am Anfang der App zu verhindern, gibt es eine Möglichkeit, den Begrüßungsbildschirm. Dies ist nur ein nicht endgültiger Weg, den Sie verwenden müssen.

Wenn Sie den Begrüßungsbildschirm aus Ihrer Datei splash.xml anzeigen, bleibt auch dieses Problem dasselbe.

Sie müssen also einen ont-Stil in der style.xml-Datei für den Begrüßungsbildschirm erstellen. Dort müssen Sie den Fensterhintergrund als Begrüßungsbild festlegen und dieses Design dann aus der Manifest-Datei auf Ihre Splash-Aktivität anwenden. Wenn Sie nun die App ausführen, wird zuerst das Thema festgelegt. Auf diese Weise können Benutzer direkt ein Splash-Bild anstelle eines weißen Bildschirms sehen.

2
Vickyexpert

In den Antworten fehlt der empfohlene Weg zur Lösung dieses Problems. Ich füge hier meine Antwort hinzu. Das Problem mit dem weißen Bildschirm beim Start tritt auf, weil der Systemprozess beim Starten der App einen leeren Bildschirm anzeigt. Um dieses Problem zu lösen, können Sie den Anfangsbildschirm deaktivieren, indem Sie ihn Ihrer styles.xml-Datei hinzufügen.

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

Laut Android-Dokumentation kann dies jedoch zu längeren Startzeiten führen. Es wird empfohlen, diesen ersten weißen Bildschirm nach Ansicht von Google zu vermeiden, indem Sie das windowBackground-Attribut der Aktivität verwenden und eine einfache benutzerdefinierte Zeichnung für die Startaktivität bereitstellen. 

So was:

Zeichenbare Layoutdatei, 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>

Erstellen Sie einen neuen Stil in Ihrem 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>

Fügen Sie dieses Thema Ihrer Startaktivität in der Manifest-Datei hinzu 

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

Und wenn Sie zu Ihrem normalen Theme-Aufruf setTheme(R.style.Apptheme) zurückkehren möchten, bevor Sie super.onCreate() und setContentView() aufrufen 

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);
    // ...
  }
}

Dies ist der empfohlene Weg, um das Problem zu lösen, und zwar von Google Material Design pattern.

2
Sam

Beide Eigenschaften funktionieren

    <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

Ich habe die folgenden zwei Zeilen in mein Theme Unter styles.xml eingefügt

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

Lief wie am Schnürchen

0

Schreiben Sie den Artikel einfach in values ​​/ styles.xml:

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

Zum Beispiel in der 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

Bitte versuchen Sie es einmal.

1) Erstellen Sie eine zeichnungsfähige Datei 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) Fügen Sie dies in styles.xml ein

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

3) Setzen Sie in Ihrer AndroidMainfest.xml das obige Thema auf Aktivität starten.

       <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