it-swarm.com.ru

Android - Запретить белый экран при запуске

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

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

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

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

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

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

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

Заметка:

Я уже упоминал следующие вопросы:

Рекомендации:

66
Y.S.

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

который даст такой эффект

a busy cat

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

55
Ivan Milisavljevic

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

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

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

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

17
Shmuel

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

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

Вы пытались установить для атрибута Android:windowBackground в теме своего действия по запуску либо цвет, либо рисунок?

Например это: 

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

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

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

7
George Metaxas

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

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

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

6
Hiren Patel

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

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

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

 enter image description here

6
Michele La Ferla

Вы пытались поместить инициализацию в 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) {

            }
        });
2
Sergey Shustikov

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

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

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

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

2
Vickyexpert

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

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

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

Как это:

Drawable Layout file, 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 Patterns.

2
Sam

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

    <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

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

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

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

0
Akanshi Srivastava

Просто напишите элемент в values ​​/ 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>
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