Android - Предотвращение появления белого экрана при запуске
Как мы все знаем, многие приложения для Android отображают белый экран очень ненадолго, прежде чем их первое Activity
попадет в фокус. Эта проблема наблюдается в следующих случаях:
Приложения для Android, расширяющие глобальный
Application
класс и выполняющие в нем основные инициализации.Application
Объект всегда создается раньше первогоActivity
(факт, который можно наблюдать в отладчике), так что это имеет смысл. В моем случае это причина задержки.Приложения для Android, которые отображают окно предварительного просмотра по умолчанию перед заставкой.
Настройка android:windowDisablePreview = "true"
очевидно, что здесь не работает. Я также не могу установить родительскую тему заставки на Theme.Holo.NoActionBar
как описано здесь, потому что [к сожалению] моя заставка использует ActionBar
.
Между тем, приложения, которые не расширяют Application
класс , не показывают белый экран при запуске.
Дело в том, что в идеале инициализации, выполняемые в Application
объекте, должны происходить до того, как будет показана первая Activity
. Итак, мой вопрос в том, как я могу выполнить эти инициализации при запуске приложения без использования Application
объекта? Возможно, используя Thread
или Service
, я полагаю?
Это интересная проблема для размышления. Я не могу обойти это обычным способом (установив NoActionBar
тему), так как, к сожалению, на моей заставке действительно есть ActionBar
по некоторым несвязанным причинам.
Примечание:
Я уже обращался к следующим вопросам:
Ссылки:
Переведено автоматически
Ответ 1
пожалуйста, добавьте эту строку в тему вашего приложения
<item name="android:windowDisablePreview">true</item>
для получения дополнительной информации: https://developer.android.com/topic/performance/vitals/launch-time#themed
Ответ 2
Проблема с белым фоном возникает из-за холодного запуска Android во время загрузки приложения в память, и ее можно избежать с помощью этого:
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();
}
}
}
макет
<?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>
изображение
<?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>
Добавьте эту тему на свой заставочный экран в манифесте
<?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>
который приведет к подобному эффекту
для получения более подробной информации и дополнительных решений вы можете проверить этот пост в блоге
Ответ 3
Рекомендуемый способ решения этой проблемы отсутствует в ответах. Поэтому я добавляю свой ответ сюда. Проблема с белым экраном при запуске возникает из-за начального пустого экрана, который системный процесс отображает при запуске приложения. Распространенный способ решить эту проблему - отключить этот начальный экран, добавив это в свой styles.xml
файл.
<item name="android:windowDisablePreview">true</item>
Но, согласно документации Android, это может привести к увеличению времени запуска. Рекомендуемый способ избежать этого начального белого экрана, согласно Google, - использовать windowBackground
атрибут theme activity и предоставить простой пользовательский чертеж для начального действия.
Вот так:
Файл макета с возможностью рисования, 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>
Создайте новый стиль в своем 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>
Добавьте эту тему в начальное действие в файле манифеста
<activity ...
android:theme="@style/AppTheme.Launcher" />
И когда вы хотите вернуться к своей обычной теме, вызовите setTheme(R.style.Apptheme)
перед вызовом super.onCreate()
и 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);
// ...
}
}
Это рекомендуемый способ решения проблемы, и он взят из шаблонов Google Material Design.
Ответ 4
Пожалуйста, скопируйте и вставьте эти две строки в тему вашего приложения-манифеста, т.е. res / styles / AppTheme. тогда все будет работать как по маслу..
<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>