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:
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
weitere Informationen und Lösungen finden Sie hier BlogPost
bitte fügen Sie diese Zeile in Ihr App-Design ein
<item name="Android:windowDisablePreview">true</item>
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.
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>
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.
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:
Hoffe das würde dir helfen.
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:
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) {
}
});
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.
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.
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>
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
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>
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>
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>