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


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

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

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

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

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

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

14 59

14 ответов:

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

добавить эту тему на ваш splashscreen в манифесте

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

enter image description here

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

стиль.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

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

свойства работы

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

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

            }
        });

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

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

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

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

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

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

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

такой:

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 Материал Дизайн шаблоны.

просто напишите элемент в значениях / стилях.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>

Я бы рекомендовал взглянуть на ответ, данный на на этой странице. Решается с помощью свойства 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>