Подтвердить что ты не робот

Android - предотвращение белого экрана при запуске

Как мы все знаем, многие приложения для Android отображают белый экран очень кратко, прежде чем их первый Activity станет в фокусе. Эта проблема наблюдается в следующих случаях:

  • Приложения Android, расширяющие глобальный класс Application и выполните основные инициализации. Application объект всегда создается до первого Activity (факт, который может наблюдаются в отладчике), поэтому это имеет смысл. Это является причиной задержки в моем случае.

  • Android-приложения, отображающие окно предварительного просмотра по умолчанию перед заставкой.

Настройка android:windowDisablePreview = "true" явно не работает. Я также не могу установить родительскую тему заставки на Theme.Holo.NoActionBar, как описано здесь, потому что [к сожалению] мой заставку использует ActionBar.

В то же время приложения, которые не расширяют класс Application не, отображают белый экран при запуске.

Дело в том, что в идеале инициализации, выполняемые в объекте Application, должны возникать до появления первого Activity. Итак, мой вопрос: как я могу выполнить эти инициализации при запуске приложения без использования объекта Application? Возможно, используя Thread или Service, я полагаю?

Это интересная проблема, о которой нужно подумать. Я не могу обойти это обычным способом (установив тему NoActionBar), так как трагически мой экран Splash на самом деле имеет ActionBar из-за некоторых не связанных причин.

Примечание:

Я уже говорил о следующих вопросах:

Литература:

4b9b3361

Ответ 1

Проблема с белым фоном возникает из-за холодного запуска 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>

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>

Добавьте эту тему в свой всплывающий экран в манифесте

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

который будет производить такой эффект

a busy cat

для получения более подробной информации и других решений, вы можете проверить это BlogPost

Ответ 2

добавьте эту строку в тему приложения

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

Ответ 3

Пожалуйста, скопируйте и вставьте эти две строки в тему вашего манифеста, т.е. res/styles/AppTheme. тогда это будет работать как шарм..

<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>

Ответ 4

Прежде всего, чтобы удалить белый экран, прочитайте это - https://www.bignerdranch.com/blog/splash-screens-the-right-way/

Но что более важно, оптимизируйте свою начальную нагрузку и отложите любую тяжелую работу, когда у вас есть время ее запустить. Отправьте свой класс приложений здесь, если хотите, чтобы мы посмотрели его.

Ответ 5

Попробовали ли вы установить атрибут android:windowBackground в теме своей активности запуска, либо в цвет, либо на чертеж?

Например:

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

при добавлении в тему активности Launcher будет отображаться черный цвет (а не белый цвет) при запуске. Это простой трюк, чтобы скрыть длительную инициализацию, показывая вашим пользователям что-то, , и он отлично работает, даже если вы подклассифицируете объект Application.

Избегайте использования других конструктов (даже потоков) для выполнения длинных задач инициализации, потому что вы не сможете управлять жизненным циклом таких конструкций. Объект Application - это правильное место для выполнения такого рода действий.

Ответ 6

В методах обратного вызова жизненного цикла вы можете объявить, как ведет себя ваша деятельность, когда пользователь покидает ее и снова входит в нее. Помните, что у Android есть жизненный цикл для каждого приложения. Если вы слишком сильно загрузите метод onCreate() (который используется для загрузки файлов макета и инициализации всех имеющихся в нем элементов управления), тогда белый экран станет более видимым, так как для файла макета потребуется больше времени. нагрузки.

Я предлагаю использовать несколько разных методов при запуске деятельности. Это onStart() (вызываемый первым после загрузки приложения), onActivityCreated() (вызываемый после отображения макета и полезный, если вы выполняете какую-либо обработку данных при запуске действия).

Чтобы вам было легче, ниже приведена официальная диаграмма жизненного цикла активности:

enter image description here

Ответ 7

У меня была та же проблема, вы должны обновить свой стиль.

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>

Ваш файл манифеста должен выглядеть следующим образом.

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

Outout:

enter image description here

Надеюсь, это поможет вам.

Ответ 8

Рекомендуемый способ решения этой проблемы отсутствует в ответах. Поэтому я добавляю свой ответ здесь. Проблема белого экрана при запуске возникает из-за начального пустого экрана, который системный процесс рисует при запуске приложения. Распространенный способ решить эту проблему - отключить начальный экран, добавив его в свой файл styles.xml.

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

Но, согласно документации Android, это может привести к увеличению времени запуска. Рекомендуемый способ избежать этого начального белого экрана в соответствии с Google - использовать windowBackground темы windowBackground и предоставить простую пользовательскую отрисовку для начального действия.

Как это:

Файл макета Drawable, 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.

Ответ 9

Я добавил следующие две строки в мою тему в файле styles.xml.

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

Работал как шарм

Ответ 10

Вы пытались инициализировать onActivityCreated?

Внутри класса 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) {

            }
        });

Ответ 11

Как вы уже знаете, почему этот белый экран есть, так как из-за фоновых процессов или инициализации приложений или больших файлов, так что просто проверьте ниже идею для преодоления этого.

Чтобы предотвратить появление этого белого экрана в начале приложения, одним из способов является экран заставки, это просто не окончательный вариант, и вы должны использовать его.

Когда вы покажете заставку из вашего файла splash.xml, тогда эта проблема останется такой же,

Итак, вам нужно создать стиль ont в файле style.xml для экрана заставки, и вам нужно установить фоновый фон в качестве изображения для всплеска, а затем применить эту тему к вашей активности всплеска из файла манифеста. Итак, теперь, когда вы запустите приложение, сначала установите тему, и таким образом пользователь сможет видеть непосредственно заставку вместо белого экрана.

Ответ 12

Оба свойства работают

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

Ответ 13

Просто напишите элемент в значениях /styles.xml:

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

Например, в 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>

Ответ 14

Белый фон исходит от Apptheme. Вы можете показать что-то полезное, например, логотип вашего приложения вместо белого экрана. Это можно сделать с помощью пользовательской темы. В вашем приложении Theme просто добавьте

android:windowBackground=""

приписывать. Значением атрибута может быть изображение или многоуровневый список или любой цвет.

Я бы рекомендовал взглянуть на ответ, приведенный на этой странице.

Ответ 15

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>

Ответ 16

Пожалуйста, попробуйте это один раз.

1) Создайте файл для рисования 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) Поместите это в styles.xml

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

3) В вашем AndroidMainfest.xml установите вышеуказанную тему для запуска.

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