java - Android: evitar pantalla blanca al inicio
multithreading performance (15)
¿Has intentado configurar el atributo
android:windowBackground
en el tema de tu actividad de
android:windowBackground
, ya sea en color o dibujable?
Por ejemplo esto:
<item name="android:windowBackground">@android:color/black</item>
cuando se agrega al tema de actividad del Iniciador, se mostrará un color negro (en lugar del color blanco) al inicio. Este es un truco fácil para ocultar una inicialización larga, mientras muestra a sus usuarios algo, y funciona bien incluso si subclasifica el objeto Aplicación.
Evite el uso de otras construcciones (incluso subprocesos) para realizar tareas de inicialización largas, ya que es posible que no pueda controlar el ciclo de vida de tales construcciones. El objeto Aplicación es el lugar correcto para realizar exactamente este tipo de acciones.
Como todos sabemos, muchas aplicaciones de Android muestran una pantalla en blanco muy brevemente antes de que se enfoque su primera
Activity
.
Este problema se observa en los siguientes casos:
-
Aplicaciones de Android que amplían la clase de
Application
global y realizan importantes inicializaciones en ella. El objetoApplication
siempre se crea antes de la primeraActivity
(un hecho que se puede observar en el depurador), por lo que tiene sentido. Esta es la causa de la demora en mi caso. -
Aplicaciones de Android que muestran la ventana de vista previa predeterminada antes de la pantalla de inicio.
Configurar
android:windowDisablePreview = "true"
obviamente no funciona aquí.
Tampoco puedo establecer el tema principal de la pantalla de
Theme.Holo.NoActionBar
en
Theme.Holo.NoActionBar
como se describe
here
, porque [desafortunadamente] mi pantalla de
ActionBar
hace uso de un
ActionBar
.
Mientras tanto, las aplicaciones que no extienden la clase
Application
no
muestran la pantalla en blanco al inicio.
La cuestión es que, idealmente, las inicializaciones realizadas en el objeto
Application
deben ocurrir
antes de que
se muestre la primera
Activity
.
Entonces mi pregunta es, ¿cómo puedo realizar estas inicializaciones en el inicio de la aplicación
sin
usar un objeto
Application
?
Posiblemente usando un
Thread
o
Service
, supongo.
Este es un problema interesante para pensar.
No puedo
NoActionBar
la manera habitual (configurando el tema
NoActionBar
), ya que trágicamente mi pantalla Splash en realidad tiene una
ActionBar
debido a algunas razones no relacionadas.
Nota:
Ya me he referido a las siguientes preguntas:
-
¿Cómo arreglar la pantalla blanca en la aplicación de inicio?
-
¿La pantalla de inicio de Android es blanca al principio?
-
Pantalla blanca antes de la pantalla de bienvenida
-
Fondo blanco cuando se inicia la aplicación de Android
-
¿Por qué aparece una pantalla en blanco durante 1 segundo al comenzar a ejecutar las aplicaciones en Android?
Referencias
¿Intentaste poner la inicialización en
onActivityCreated
?
Clase de
Application
interior:
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) {
}
});
Agregué las siguientes dos líneas en mi tema en styles.xml
<item name="android:windowDisablePreview">true</item>
<item name="android:windowBackground">@null</item>
Trabajado como un encanto
Ambas propiedades funcionan
<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>
Como ya sabe por qué esta pantalla blanca está allí, debido a procesos en segundo plano o inicialización de la aplicación o archivos grandes, así que simplemente verifique la idea a continuación para superarla.
Para evitar esta pantalla blanca al comienzo de la aplicación, una forma es la pantalla de inicio, esta es solo una forma no final y debe usarla.
Cuando muestre la pantalla de bienvenida desde su archivo splash.xml, entonces este problema seguirá siendo el mismo,
Por lo tanto, debe crear un estilo único en el archivo style.xml para la pantalla de presentación y allí debe establecer el fondo de la ventana como imagen de presentación y luego aplicar ese tema a su actividad de presentación desde el archivo de manifiesto. Entonces, cuando ejecute la aplicación, primero establecerá el tema y de esta manera el usuario podrá ver directamente la imagen de bienvenida en lugar de la pantalla en blanco.
Copie y pegue estas dos líneas en el tema de la aplicación de manifiesto, es decir, res / styles / AppTheme. entonces funcionará como encanto ...
<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>
Dentro de los métodos de devolución de llamada del ciclo de vida, puede declarar cómo se comporta su actividad cuando el usuario abandona y vuelve a ingresar a la actividad.
Recuerde que la forma en que está diseñado Android, hay un ciclo de vida para todas y cada una de las aplicaciones.
Si pone demasiada carga en el método
onCreate()
(que es el método utilizado para cargar los archivos de diseño e inicializar cualquier control que tenga), la pantalla en blanco será más visible, ya que el archivo de diseño tardará más en carga.
Sugiero usar varios métodos diferentes al comenzar una actividad.
Tales son
onStart()
(que se llama como lo primero una vez que se carga la aplicación),
onActivityCreated()
(que se llama después de que se muestre el diseño y es útil si está realizando algún procesamiento de datos al comenzar la actividad).
Para hacerlo más fácil, a continuación se muestra el diagrama oficial del ciclo de vida de la actividad:
El problema con el fondo blanco se debe al inicio en frío de Android mientras la aplicación se carga en la memoria, y se puede evitar con esto:
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();
}
}
}
diseño
<?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>
cara de img
<?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>
Agregue este tema a su pantalla de presentación en el manifiesto
<?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>
que producirá un efecto como este
para más detalles y más soluciones puedes consultar este BlogPost
En primer lugar, para eliminar la pantalla en blanco, lea esto: https://www.bignerdranch.com/blog/splash-screens-the-right-way/
Pero lo más importante, optimice su carga inicial y difiera cualquier trabajo pesado cuando tenga tiempo para ejecutarlo. Publique su clase de solicitud aquí si desea que le echemos un vistazo.
Falta la forma recomendada de resolver este problema en las respuestas.
Entonces agrego mi respuesta aquí.
El problema de la pantalla blanca al inicio se produce debido a la pantalla en blanco inicial que dibuja el proceso del sistema al iniciar la aplicación.
Una forma común de resolver esto es apagando esta pantalla inicial agregando esto a su archivo
styles.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>
Pero de acuerdo con la documentación de Android, esto puede resultar en un mayor tiempo de inicio.
La forma recomendada de evitar esta pantalla blanca inicial según Google es usar el
windowBackground
tema
windowBackground
la actividad y proporcionar un
windowBackground
personalizado simple para la actividad inicial.
Me gusta esto:
Archivo de diseño
my_drawable.xml
,
my_drawable.xml
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
// Other stuff
</application>
Crea un nuevo estilo en tu
styles.xml
<item name="android:windowDisablePreview">true</item>
Agregue este tema a su actividad inicial en el archivo de manifiesto
<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>
Y cuando desee volver a la transición a su tema normal, llame a
setTheme(R.style.Apptheme)
antes de llamar a
super.onCreate()
y
setContentView()
<!-- 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>
Esta es la forma recomendada de resolver el problema y esto es de los patrones de Google Material Design .
Por favor intente esto una vez.
1) Crear un archivo dibujable 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) Pon esto en styles.xml
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/background_splash</item>
</style>
3) En su AndroidMainfest.xml configure el tema anterior para Iniciar actividad.
<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>
Simplemente escriba el elemento en values / styles.xml:
<item name="android:windowBackground">@android:color/black</item>
Por ejemplo, en el 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>
Tuve el mismo problema, tienes que actualizar tu estilo.
style.xml
<activity ...
android:theme="@style/AppTheme.Launcher" />
Su archivo de manifiesto debería verse a continuación.
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);
// ...
}
}
Fuera fuera:
Espero que esto te ayude.
agregue esta línea al tema de su aplicación
<item name="android:windowDisablePreview">true</item>
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>