Как мне сделать заставку?


548

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

Как бы я его создал и затем реализовал?


58
Почему приложение выглядит более профессионально с помощью заставки? Я не знаю ни одного «профессионального» приложения для Android, в котором оно есть.
Теомега

7
Согласился с @theomega. Заставки просто раздражают.
Мэтт Болл

85
Вы должны показывать заставку, только если у вас есть фоновая загрузка. В противном случае ваше приложение выглядит более «профессионально», когда вы даете пользователю то, что он хочет от вашего приложения, как можно быстрее. Пользователи замечают (и раздражаются) задержки свыше 100 мс, и вы добавляете заставку на порядок выше этого порога.
CodeFusionMobile

74
kindle app, aldiko (читатель), дельфин .. Ммм ОС :) Они все получили всплеск. Opera Mobile, Mantan Reader, Карты. Я мог бы продолжить. Если он скрывает загрузку, то он хотя бы сообщает пользователю, что ваше приложение запущено. Задержка в несколько секунд скрывается гораздо лучше, когда на экране есть хоть что-то из вас.
baash05

9
Заставка дает вам отличную возможность рекламировать название вашей игры или приложения или логотип компании. Мне нравится делать заставку кликабельной, чтобы у пользователя была возможность перейти к игре. Если пользователь всегда видит логотип вашей компании даже на полсекунды каждый раз, когда открывает приложение, он с большей вероятностью вспомнит, кто вы, черт возьми. Просто убедитесь, что они имеют хороший опыт работы с вашим приложением.
Chamatake-san

Ответы:


509

Дальнейшее чтение:

Старый ответ:

КАК : Простая заставка

В этом ответе показано, как отображать заставку в течение фиксированного периода времени, когда ваше приложение запускается, например, из-за брендинга. Например, вы можете показывать заставку в течение 3 секунд. Однако, если вы хотите показывать экран-заставку в течение различного промежутка времени (например, время запуска приложения), вам следует проверить ответ Абдуллы https://stackoverflow.com/a/15832037/401025 . Однако имейте в виду, что запуск приложений может быть очень быстрым на новых устройствах, поэтому пользователь просто увидит вспышку, которая является плохим UX.

Для начала вам нужно определить заставку в вашем layout.xmlфайле

  <?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical" android:layout_width="fill_parent"
          android:layout_height="fill_parent">

          <ImageView android:id="@+id/splashscreen" android:layout_width="wrap_content"
                  android:layout_height="fill_parent"
                  android:src="@drawable/splash"
                  android:layout_gravity="center"/>

          <TextView android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="Hello World, splash"/>

  </LinearLayout>

И ваша деятельность:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

public class Splash extends Activity {

    /** Duration of wait **/
    private final int SPLASH_DISPLAY_LENGTH = 1000;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.splashscreen);

        /* New Handler to start the Menu-Activity 
         * and close this Splash-Screen after some seconds.*/
        new Handler().postDelayed(new Runnable(){
            @Override
            public void run() {
                /* Create an Intent that will start the Menu-Activity. */
                Intent mainIntent = new Intent(Splash.this,Menu.class);
                Splash.this.startActivity(mainIntent);
                Splash.this.finish();
            }
        }, SPLASH_DISPLAY_LENGTH);
    }
}

Это все ;)


3
@ user2606414, пожалуйста, создайте вопрос о SO для вашей проблемы и вставьте весь журнал ошибок.
Upvote

39
Не забудьте добавить всплеск в манифесте
Zar E Ahmer

8
@ Петр, вопрос не в том, как показать заставку при загрузке данных.
Upvote

18
Это не правильное решение для заставки, оно заставляет пользователя ждать показа заставки, однако назначение заставки наоборот. Он должен показывать заставку, пока пользователь ждет. Пожалуйста, смотрите решение @ Abdullah.
Efeyc

4
Вместо того, чтобы останавливать приложение на SPLASH_DISPLAY_LENGTHвремя. Вы должны сделать это вместо этого: bignerdranch.com/blog/splash-screens-the-right-way
miguel.martin

596

Обратите внимание, что это решение не позволит пользователю больше ждать: задержка заставки зависит от времени запуска приложения.

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

Сначала создайте style.xml в папке значений и добавьте в него стиль.

<style name="splashScreenTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_screen</item>
</style>

Вместо использования @android:style/Theme.DeviceDefault.Light.NoActionBarвы можете использовать любую другую тему в качестве родительской.

Во-вторых, добавьте в свое приложение Manifest.xml android:theme="@style/splashScreenTheme"к своей основной деятельности.

<activity
        android:name="MainActivity"
        android:label="@string/app_name"
        android:theme="@style/splashScreenTheme" >

В-третьих, обновите свою тему в своей деятельности по запуску onCreate ().

protected void onCreate(Bundle savedInstanceState) {
    // Make sure this is before calling super.onCreate
    setTheme(R.style.mainAppTheme);
    super.onCreate(savedInstanceState);
}

ОБНОВЛЕНИЕ Проверьте этот пост .

Благодаря @ mat1h и @adelriosantiago


3
Похоже, «родитель» поддерживается только в API 14 и выше
user1832478

104
Это правильный способ сделать заставку. Спасибо! Ответ с большим количеством голосов с задержками - просто плохая практика. Ничто не должно задерживать пользователя от просмотра первого функционального экрана.
Динет

7
Одна проблема, с которой я столкнулся, заключается в том, что <item name="android:background">это переопределило бы windowBackground. И без android:backgroundопределения мой фон в любых фрагментах был бы прозрачным, показывая активность за содержанием переднего плана.
Уильям Гранд

4
@Abdullah: я следовал за тем, как ты сказал. Он работает нормально, но заставка появляется на несколько миллисекунд при переходах активности.
nizam.sp

3
@Abdullah Спасибо! Это было бы возможным решением, однако я нашел это: plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd , чтобы избежать создания разных изображений для каждого размера экрана, также можно создать XML, содержащий изображение, чтобы оно выглядело хорошо на всех экранах.
adelriosantiago

52
  • Создать мероприятие: Splash
  • Создайте XML-файл макета: splash.xml
  • Поместите компоненты пользовательского интерфейса в макет splash.xml, чтобы он выглядел так, как вы хотите
  • ваш Splash.java может выглядеть так:

    public class Splash extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.splash);
    
            int secondsDelayed = 1;
            new Handler().postDelayed(new Runnable() {
                    public void run() {
                            startActivity(new Intent(Splash.this, ActivityB.class));
                            finish();
                    }
            }, secondsDelayed * 1000);
        }
    }
  • перейдите ActivityB.classк любой активности, которую вы хотите начать после заставки

  • проверьте файл манифеста, и он должен выглядеть

        <activity
            android:name=".HomeScreen"
            android:label="@string/app_name">     
        </activity>

        <activity
            android:name=".Splash"
            android:label="@string/title_activity_splash_screen">     
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

28
Это не цель заставки. Это делает дополнительную задержку в 1 секунду. Экран-заставка должен быть изображением при загрузке первого экрана приложения. Эта ссылка может помочь. stackoverflow.com/a/7057332/869451
efeyc

2
@efeyc: вы на 100% правы ... пока выглядит приложение довольно неплохо, не правда ли?
Маклан

1
@ Suda.nese определенно нет. Пользователи не хотят смотреть на картинку, пользователи хотят использовать приложение и не имеют ненужной задержки
Тим

1
@TimCastelijns Это зависит от разрабатываемого приложения и от того, как выглядит заставка ... конечно, это должно быть практично, но кто сказал, что его нельзя использовать иначе !!
Маклан

6
Согласен @ Suda.nese Если требования к приложению включают заставку, то это заставка! Конечно, это может быть нежелательно для пользователей, но если клиент хочет заставку, то, черт возьми, дать им это
Джеймс

29

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

  1. Экран-заставка является точкой входа в мое приложение, поэтому добавьте следующие строки в AndroidManifest.xml.

        <activity
            android:name=".SplashActivity"
            android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  2. Заставка должна отображаться только один раз в жизненном цикле приложения, я использую логическую переменную для записи состояния заставки и показываю ее только в первый раз.

    public class SplashActivity extends Activity {
        private static boolean splashLoaded = false;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            if (!splashLoaded) {
                setContentView(R.layout.activity_splash);
                int secondsDelayed = 1;
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        startActivity(new Intent(SplashActivity.this, MainActivity.class));
                        finish();
                    }
                }, secondsDelayed * 500);
    
                splashLoaded = true;
            }
            else {
                Intent goToMainActivity = new Intent(SplashActivity.this, MainActivity.class);
                goToMainActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                startActivity(goToMainActivity);
                finish();
            }
        }
    }

Удачного кодирования!


10
Вы можете добавить android:noHistory="true"в , AndroidManifest.xmlчтобы запретить пользователю идти назад к заставке с помощью кнопки назад.
Рэйчел

15

Ответ Абдуллы великолепен. Но я хочу добавить еще несколько деталей в мой ответ.

Реализация заставки

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

Таким образом, вы не будете использовать файл макета. Вместо этого укажите фон заставки в качестве фона темы занятия. Для этого сначала создайте XML drawable в res / drawable.

background_splash.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/gray"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

Это просто список слоев с логотипом в центре цвета фона с ним.

Теперь откройте файл styles.xml и добавьте этот стиль.

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

Эта тема будет на панели действий и с фоном, который мы только что создали выше.

И в манифесте вам нужно настроить SplashTheme на активность, которую вы хотите использовать в качестве заставки.

<activity
android:name=".SplashActivity"
android:theme="@style/SplashTheme">
<intent-filter>
    <action android:name="android.intent.action.MAIN" />

    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Затем внутри вашего кода активности перейдите к конкретному экрану после заставки с помощью намерения.

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}

Это правильный способ сделать. Я использовал эти ссылки для ответа.

  1. https://material.google.com/patterns/launch-screens.html
  2. https://www.bignerdranch.com/blog/splash-screens-the-right-way/ Спасибо этим ребятам за то, что подтолкнули меня в правильном направлении. Я хочу помогать другим, потому что принятый ответ не рекомендуется использовать в качестве заставки.

1
Я видел учебник по YouTubeповоду об этом. Но я думаю, что размер растрового изображения будет проблемой, так как вы не можете изменить его размер, используя layer-list.
RoCk RoCk

14
  1. Создать Activity SplashScreen.java

    public class SplashScreen extends Activity {
    protected boolean _active = true;
    protected int _splashTime = 3000; // time to display the splash screen in ms
    
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splashscreen);
    
        Thread splashTread = new Thread() {
            @Override
            public void run() {
                try {
                    int waited = 0;
                    while (_active && (waited < _splashTime)) {
                        sleep(100);
                        if (_active) {
                            waited += 100;
                        }
                    }
                } catch (Exception e) {
    
                } finally {
    
                    startActivity(new Intent(SplashScreen.this,
                            MainActivity.class));
                    finish();
                }
            };
                 };
        splashTread.start();
    }
     }
  2. splashscreen.xml будет так

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="600px" android:layout_height="1024px"
      android:background="#FF0000">
    </RelativeLayout> 

13

По умолчанию Splash Screnn не делает ваше приложение более профессиональным. Профессионально разработанный Splash Screen имеет возможность сделать ваше приложение более профессиональным, но если вы не знаете, как его написать, то насколько профессиональным будет ваше приложение.

Единственной причиной (оправданием) появления заставки является то, что вы выполняете огромное количество вычислений или ожидаете запуска GPS / WiFi, потому что ваше приложение полагается на это до запуска. Без результатов этих вычислений или доступа к GPS / WiFi (и т. Д.) Ваше приложение замертво в воде, поэтому вы чувствуете, что вам нужен экран-заставка, и ДОЛЖЕН блокировать вид экрана для любых других работающих программ (включая фоновый) ).

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

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

На вашем телефоне уже есть значки, которые говорят, что GPS / WiFi запускается. Время или пространство, занимаемое заставкой, может быть потрачено на загрузку предварительных вычислений или выполнение вычислений. Смотрите первую ссылку ниже, чтобы узнать о проблемах, которые вы создаете, и о том, что необходимо учитывать.

Если вам абсолютно необходимо дождаться этих вычислений или GPS / WiFi, лучше всего просто запустить приложение и открыть всплывающее окно, в котором говорится, что необходимо дождаться вычислений (текстовое сообщение «Инициализация» - это нормально). Ожидается ожидание GPS / WiFi (если они еще не были включены в другой программе), поэтому нет необходимости объявлять время их ожидания.

Помните, что когда Splash Screen запускает вашу Программу, она фактически уже запущена, все, что вы делаете, это откладываете использование вашей Программы и заставляете CPU / GPU делать то, что большинство не считает необходимым.

Нам лучше действительно подождать и посмотреть ваш Splash Screen каждый раз, когда мы запускаем вашу Программу, или МЫ не будем чувствовать, что она написана очень профессионально. Создание экрана-заставки ПОЛНОГО экрана и дубликата самого экрана программы (поэтому мы думаем, что он инициализирован, хотя на самом деле это не так) МОЖЕТ достичь вашей цели (сделать вашу программу более профессионально выглядящей), но я бы не стал на это сильно ставить.

Почему бы не сделать это: http://cyrilmottier.com/2012/05/03/splash-screens-are-evil-dont-use-them/

Как это сделать: https://encrypted.google.com/search?q=Android+splash+screen+source

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

Это похоже на канал YouTube, который начинает каждое видео с длинного графического вступления (и Outro) или чувствует необходимость рассказать шутку или объяснить, что произошло на прошлой неделе (когда это не канал Comedy или LifeStyles). Просто покажи шоу! (Просто запустите программу).


12

Прежде всего ответы действительно очень хороши. Но есть проблема утечки памяти. Эта проблема часто известна в сообществе Android как «Утечка активности» . Теперь, что именно это значит?

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

«Утечка активности» относится к ситуации, когда сборщик мусора не может очистить выделенную память старого экземпляра действия, поскольку он принадлежит being (strong) referencedобъекту, который прожил экземпляр действия. Каждому приложению Android выделено определенное количество памяти. Когда сборщик мусора не может освободить неиспользуемую память, производительность приложения будет постепенно снижаться и в конечном итоге завершится с OutOfMemoryошибкой.

Как определить, утечка памяти у приложения или нет? Самый быстрый способ - открыть вкладку «Память» в Android Studio и обратить внимание на выделенную память при изменении ориентации. Если выделенная память продолжает увеличиваться и никогда не уменьшается, у вас есть утечка памяти.

1. Утечка памяти, когда пользователь меняет ориентацию. введите описание изображения здесь

Сначала вам нужно определить заставку в splashscreen.xmlфайле ресурсов макета.

Пример кода для активности на заставке.

public class Splash extends Activity {
 // 1. Create a static nested class that extends Runnable to start the main Activity
    private static class StartMainActivityRunnable implements Runnable {
        // 2. Make sure we keep the source Activity as a WeakReference (more on that later)
        private WeakReference mActivity;

        private StartMainActivityRunnable(Activity activity) {
         mActivity = new WeakReference(activity);
        }

        @Override
        public void run() {
         // 3. Check that the reference is valid and execute the code
            if (mActivity.get() != null) {
             Activity activity = mActivity.get();
             Intent mainIntent = new Intent(activity, MainActivity.class);
             activity.startActivity(mainIntent);
             activity.finish();
            }
        }
    }

    /** Duration of wait **/
    private final int SPLASH_DISPLAY_LENGTH = 1000;

    // 4. Declare the Handler as a member variable
    private Handler mHandler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(icicle);
        setContentView(R.layout.splashscreen);

        // 5. Pass a new instance of StartMainActivityRunnable with reference to 'this'.
        mHandler.postDelayed(new StartMainActivityRunnable(this), SPLASH_DISPLAY_LENGTH);
    }

    // 6. Override onDestroy()
    @Override
    public void onDestroy() {
     // 7. Remove any delayed Runnable(s) and prevent them from executing.
     mHandler.removeCallbacksAndMessages(null);

     // 8. Eagerly clear mHandler allocated memory
     mHandler = null;
    }
}

Для получения дополнительной информации перейдите по этой ссылке


7

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

Таким образом, вы не будете использовать файл макета. Вместо этого укажите фон заставки в качестве фона темы занятия. Для этого сначала создайте XML drawable в res / drawable.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/gray"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

Здесь я настроил цвет фона и изображение.

Далее вы установите это в качестве фона вашей заставки в теме. Перейдите к файлу styles.xml и добавьте новую тему для своей активности-всплеска:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

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

</resources>

В вашем новом SplashTheme установите атрибут фона окна в свой XML-формат. Сконфигурируйте это как тему вашей заставки в вашем AndroidManifest.xml:

<activity
    android:name=".SplashActivity"
    android:theme="@style/SplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Наконец, класс SplashActivity должен просто направить вас к вашему основному виду деятельности:

     public class SplashActivity extends AppCompatActivity {

             @Override
             protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

               Intent intent = new Intent(this, MainActivity.class);
               startActivity(intent);
               finish();
    }
}

Подробнее читайте здесь: 1. https://www.bignerdranch.com/blog/splash-screens-the-right-way/ 2. http://blog.goodbarber.com/3-tips-to-create-a -Большая-заставка-для-вашей-подвижной app_a287.html


4

Это полный код здесь

SplashActivity.java

public class SplashActivity extends AppCompatActivity {

private final int SPLASH_DISPLAY_DURATION = 1000;

@Override
public void onCreate(Bundle bundle) {
    super.onCreate(bundle);


    new Handler().postDelayed(new Runnable(){
        @Override
        public void run() {

            Intent mainIntent = new Intent(SplashActivity.this,MainActivity.class);
            SplashActivity.this.startActivity(mainIntent);
            SplashActivity.this.finish();
        }
    }, SPLASH_DISPLAY_DURATION);
}}

В Drawables создать этот bg_splash.xml

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item
    android:drawable="@color/app_color"/>

<item>
    <bitmap
        android:gravity="center"
        android:src="@drawable/ic_in_app_logo_big"/>
</item></layer-list>

В styles.xml создайте собственную тему

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

и наконец в AndroidManifest.xml укажите тему вашей деятельности

<activity
        android:name=".activities.SplashActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:theme="@style/SplashTheme">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Приветствия.


Как добавить файл XML вместоdrawable
гадюки

Я имею в виду, что вам нужно создать bg_splash.xml в каталоге drawable, как описано выше.
awsleiman

4

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

Лучший способ - создать тему только для вашей SplashScreenActivity и задать the android:windowBackgroundдля нее доступный ресурс.

https://www.bignerdranch.com/blog/splash-screens-the-right-way/

В двух словах:

Объявите свою SplashScreenActivity в манифесте:

<activity
        android:name=".activities.SplashScreenActivity"
        android:theme="@style/SplashTheme"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

В вашем SplashScreenActivity.java:

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = new Intent(this, MainActivity_.class);
    startActivity(intent);
    finish();

}

Затем создайте ресурс для фонового окна вашей темы:

<style name="SplashTheme" parent="Theme.Bumpfie.Base">
    <item name="android:windowBackground">@drawable/splash</item>
</style>

Drawable файл splash.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/app_logo"/>
    </item>
</layer-list>

4

После Android Marshmallow другое продуктивное использование экрана-заставки, о котором я вспоминаю, - запросить необходимоеAndroid Permissions на экране-заставке вашего приложения.

похоже, что большинство приложений обрабатывают запрос на разрешение таким образом.

  • Диалоги делают UIX плохим, и они нарушают основной поток и заставляют вас выбирать время выполнения, и правда заключается в том, что большинству пользователей может быть даже наплевать, хочет ли ваше приложение что-то записать на SD-карту. Некоторые из них могут даже не понимать, что мы пытаемся передать, пока не переведем это на простой английский.

  • Одновременный запрос разрешений уменьшает количество операций «if else» перед каждой операцией и делает ваш код более свободным.

Это пример того, как вы можете запрашивать разрешения в вашей заставке для устройства под управлением Android OS 23+.

Если все разрешения предоставлены, ИЛИ уже предоставлены, ИЛИ приложение запущено в Pre Marshmallow THEN, просто перейдите и отобразите основное содержание с небольшой задержкой в ​​полсекунды, чтобы пользователь мог оценить усилия, которые мы приложили при чтении этого вопроса и стараемся изо всех сил.

import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.c2h5oh.beer.R;
import com.c2h5oh.beer.utils.Animatrix;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SplashActivity extends AppCompatActivity {

    final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);

        //show animations 
        Animatrix.scale(findViewById(R.id.title_play), 100);
        Animatrix.scale(findViewById(R.id.title_edit), 100);
        Animatrix.scale(findViewById(R.id.title_record), 100);
        Animatrix.scale(findViewById(R.id.title_share), 100);

        if (Build.VERSION.SDK_INT >= 23) {

            // Marshmallow+ Permission APIs
            fuckMarshMallow();

        } else {

            // Pre-Marshmallow
            ///Display main contents
            displaySplashScreen();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
                Map<String, Integer> perms = new HashMap<String, Integer>();
                // Initial
                perms.put(Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.MODIFY_AUDIO_SETTINGS, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.VIBRATE, PackageManager.PERMISSION_GRANTED);
                // Fill with results
                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);

                // Check for ACCESS_FINE_LOCATION
                if (perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.MODIFY_AUDIO_SETTINGS) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.VIBRATE) == PackageManager.PERMISSION_GRANTED) {
                    // All Permissions Granted

                    // Permission Denied
                    Toast.makeText(SplashActivity.this, "All Permission GRANTED !! Thank You :)", Toast.LENGTH_SHORT)
                            .show();

                    displaySplashScreen();

                } else {
                    // Permission Denied
                    Toast.makeText(SplashActivity.this, "One or More Permissions are DENIED Exiting App :(", Toast.LENGTH_SHORT)
                            .show();

                    finish();
                }
            }
            break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }


    @TargetApi(Build.VERSION_CODES.M)
    private void fuckMarshMallow() {
        List<String> permissionsNeeded = new ArrayList<String>();

        final List<String> permissionsList = new ArrayList<String>();
        if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE))
            permissionsNeeded.add("Read SD Card");
        if (!addPermission(permissionsList, Manifest.permission.RECORD_AUDIO))
            permissionsNeeded.add("Record Audio");
        if (!addPermission(permissionsList, Manifest.permission.MODIFY_AUDIO_SETTINGS))
            permissionsNeeded.add("Equilizer");
        if (!addPermission(permissionsList, Manifest.permission.VIBRATE))
            permissionsNeeded.add("Vibrate");

        if (permissionsList.size() > 0) {
            if (permissionsNeeded.size() > 0) {

                // Need Rationale
                String message = "App need access to " + permissionsNeeded.get(0);

                for (int i = 1; i < permissionsNeeded.size(); i++)
                    message = message + ", " + permissionsNeeded.get(i);

                showMessageOKCancel(message,
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                            }
                        });
                return;
            }
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
            return;
        }

        Toast.makeText(SplashActivity.this, "No new Permission Required- Launching App .You are Awesome!!", Toast.LENGTH_SHORT)
                .show();

        displaySplashScreen();
    }


    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(SplashActivity.this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }

    @TargetApi(Build.VERSION_CODES.M)
    private boolean addPermission(List<String> permissionsList, String permission) {

        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission);
            // Check for Rationale Option
            if (!shouldShowRequestPermissionRationale(permission))
                return false;
        }
        return true;
    }

    /**
     * Display main content with little delay just so that user can see
     * efforts I put to make this page
     */
    private void displaySplashScreen() {
        new Handler().postDelayed(new Runnable() {

        /*
         * Showing splash screen with a timer. This will be useful when you
         * want to show case your app logo / company
         */

            @Override
            public void run() {
                startActivity(new Intent(SplashActivity.this, AudioPlayerActivity.class));
                finish();
            }
        }, 500);
    }


}

4

Вы не будете использовать файл макета. Вместо этого укажите фон заставки в качестве фона темы занятия. Для этого сначала создайте XML drawable в res / drawable.

Примечание: весь код ниже доступен GitHub Link

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/gray"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

Здесь я настроил цвет фона и изображение.

Далее вы установите это в качестве фона вашей заставки в теме. Перейдите к файлу styles.xml и добавьте новую тему для своей активности-всплеска:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

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

</resources>

В вашем новом SplashTheme установите атрибут фона окна в свой XML-формат. Сконфигурируйте это как тему вашей заставки в вашем AndroidManifest.xml:

<activity
    android:name=".SplashActivity"
    android:theme="@style/SplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Наконец, ваш класс SplashActivity должен просто направить вас к основной деятельности:

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}

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

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


3
public class MainActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Thread t=new Thread()
    {

        public void run()
        {   

            try {

                sleep(2000);
                finish();
                Intent cv=new Intent(MainActivity.this,HomeScreen.class/*otherclass*/);
                startActivity(cv);
            } 

            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    t.start();
}

2

Создайте Activity, позвольте нам Activity с именем «A», затем создайте xml-файл с именем myscreen.xml, в котором установите изображение заставки в качестве фона, а затем используйте таймер обратного отсчета для перехода от одного Activtity к другому. Чтобы узнать, как использовать таймер обратного отсчета, см. Мой ответ на этот вопрос TimerTask в Android?


2

Пример заставки:

public class MainActivity extends Activity {
    private ImageView splashImageView;
    boolean splashloading = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        splashImageView = new ImageView(this);
        splashImageView.setScaleType(ScaleType.FIT_XY);
        splashImageView.setImageResource(R.drawable.ic_launcher);
        setContentView(splashImageView);
        splashloading = true;
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            public void run() {
                splashloading = false;
                setContentView(R.layout.activity_main);
            }

        }, 3000);

    }

}

2

Заставка - это немного непригодный объект в Android: его нельзя загрузить как можно быстрее, чтобы скрыть задержку запуска основной активности. Есть две причины, чтобы использовать его: реклама и сетевые операции.

Реализация в виде диалога позволяет без промедления перейти от заставки к основному интерфейсу действий.

public class SplashDialog extends Dialog {
    ImageView splashscreen;
    SplashLoader loader;
    int splashTime = 4000;

    public SplashDialog(Context context, int theme) {
        super(context, theme);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        setCancelable(false);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                cancel();
            }
        }, splashTime);

    }
}

Планировка:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/white">

    <ImageView
        android:id="@+id/splashscreen"
        android:layout_width="190dp"
        android:layout_height="190dp"
        android:background="@drawable/whistle"
        android:layout_centerInParent="true" />

</RelativeLayout>

И начать:

public class MyActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getIntent().getCategories() != null &&  getIntent().getCategories().contains("android.intent.category.LAUNCHER")) {
            showSplashScreen();
        }
    }

    protected Dialog splashDialog;
    protected void showSplashScreen() {
        splashDialog = new SplashDialog(this, R.style.SplashScreen);
        splashDialog.show();
    }

    ...
}

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

2

Другой подход достигается с помощью CountDownTimer

@Override
public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.splashscreen);

 new CountDownTimer(5000, 1000) { //5 seconds
      public void onTick(long millisUntilFinished) {
          mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
      }

     public void onFinish() {
          startActivity(new Intent(SplashActivity.this, MainActivity.class));
          finish();
     }

  }.start();
}

2
     - Add in SplashActivity 

   public class SplashActivity extends Activity {

       private ProgressBar progressBar;
       int i=0;
       Context context;
       private GoogleApiClient googleApiClient;

       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_splash);
           context = this;

           new Handler().postDelayed(new Runnable() {
               @Override
               public void run() {
                   startActivity(new Intent(Splash.this, LoginActivity.class));
                   finish();
               }
           }, 2000);

       }

   }

  - Add in activity_splash.xml

   <RelativeLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools"
       xmlns:custom="http://schemas.android.com/apk/res-auto"
       android:background="@color/colorAccent"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       tools:context=".Splash">

       <ImageView
           android:id="@+id/ivLogo"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:src="@mipmap/icon_splash"
           android:layout_centerHorizontal="true"
           android:layout_centerVertical="true"/>


       <ProgressBar
           android:id="@+id/circle_progress"
           style="?android:attr/progressBarStyleHorizontal"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:layout_alignParentBottom="true"
           android:layout_marginBottom="5dp"
           android:max="100"
           android:progressTint="@color/green"
           android:visibility="visible" />

   </RelativeLayout>

  - Add in AndroidManifest.xml

    <activity android:name="ex.com.SplashActivity">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />

                   <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
           </activity>

Не могли бы вы также добавить некоторые объяснения, пожалуйста?
Роберт

Да, конечно ... какое объяснение вы хотите, дайте мне знать, пожалуйста.
Ашиш Кумар

2

Действительно легкий подход gr8:

  • Сначала создайте свой всплеск на следующем веб-сайте:

    https://www.norio.be/android-feature-graphic-generator/

    Выберите свой логотип и слоган, выберите свой красивый фон. измените его размер до 4096x4096.

  • Теперь загрузите это изображение и добавьте его в:

    https://apetools.webprofusion.com/app/#/tools/imagegorilla

    И сгенерируйте все необходимые заставки, все устройства, все платформы.

Наслаждайтесь!

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


1

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

<activity
        android:name=".SplashActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data android:name="launch_class" android:value="com.mypackage.MyFirstActivity" />
        <meta-data android:name="duration" android:value="5000" />
</activity>

Затем SpashActivity сам ищет метаданные для "launch_class", чтобы затем создать сам Intent. Метаданные «длительность» определяют, как долго работает заставка.

public class SplashActivity extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.activity_splash);

    ComponentName componentName = new ComponentName(this, this.getClass());

    try {
        Bundle bundle = null;
        bundle = getPackageManager().getActivityInfo(componentName, PackageManager.GET_META_DATA).metaData;
        String launch_class = bundle.getString("launch_class");
        //default of 2 seconds, otherwise defined in manifest
        int duration = bundle.getInt("duration", 2000);

        if(launch_class != null) {
            try {
                final Class<?> c = Class.forName(launch_class);

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(SplashActivity.this, c);
                        startActivity(intent);
                        finish();
                    }
                }, duration);

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
  }
}

1

Когда-нибудь пользователь сразу откроет SplashActivityи закроет, но приложение все равно зайдет MainActivityпосле SPLASH_SCREEN_DISPLAY_LENGTH.

Для предотвращения этого: в SplashActivityвы должны проверить SplashActivityзаканчивает или нет перед переходомMainActivity

public class SplashActivity extends Activity {

    private final int SPLASH_SCREEN_DISPLAY_LENGTH = 2000;

    @Override
    public void onCreate(Bundle icicle) {
        ...
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                if (!isFinishing()) {//isFinishing(): If the activity is finishing, returns true; else returns false.
                    startActivity(new Intent(SplashActivity.this, MainActivity.class));
                    finish();
                }

            }, SPLASH_SCREEN_DISPLAY_LENGTH);
        }                             
   }                                
}

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


1

Хотя есть хорошие ответы, я покажу рекомендуемый Google способ:

1) Сначала создайте Themeэкран-заставку: у вас есть тема, которая называется splashscreenThemeвашей темой запуска:

<style name="splashscreenTheme">
  <item name="android:windowBackground">@drawable/launch_screen</item>
</style>

Замечания:

android:windowBackgroundуже устанавливает ваше изображение заставки не
нужно делать это снова в пользовательском интерфейсе.

Вы также можете использовать цвет вместо рисования.

2) Установите тему для манифеста splashscreenActivity

   <activity
            android:name=".activity.splashscreenActivity"
            android:screenOrientation="portrait"
            android:theme="@style/splashscreenTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

3) убедитесь, что launch_screen drawableне находится в drawableпапке, если ваше изображение не маленькое.

Это приведет к более быстрому запуску экрана запуска и спасет вас от черного экрана

Это также позволяет избежать дополнительного оверлея


1

Это лучший пост, который я видел на заставках: http://saulmm.github.io/avoding-android-cold-starts

Saúl Molinero предлагает два различных варианта заставок: использование фона окна для анимации на начальном экране и отображение интерфейса заполнителя (это популярный выбор, который Google использует для большинства своих приложений в настоящее время).

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

Надеюсь это поможет!


1

В моем случае я не хотел создавать новую активность только для показа изображения в течение 2 секунд. Когда я MainAvtivityзапускаю свои , изображения загружаются в держатели с помощью Picasso, я знаю, что загрузка занимает около 1 секунды, поэтому я решил сделать следующее в моей MainActivity OnCreate:

splashImage = (ImageView) findViewById(R.id.spllll);

    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

    int secondsDelayed = 1;
    new Handler().postDelayed(new Runnable() {
        public void run() {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            splashImage.setVisibility(View.GONE);

        }
    }, secondsDelayed * 2000);

При запуске приложения первое, что происходит, - это ImageViewотображение на экране и удаление строки состояния путем установки флагов окна в полноэкранный режим. Затем я использовал Handlerдля запуска в течение 2 секунд, после 2 секунд я очищаю флажки на весь экран и устанавливаю видимость ImageViewдля GONE. Легко, просто, эффективно.


1

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

В вашем Java-файле SplashScreenActivity этот код в .

В вашем файле SplashScreenActivity xml поместите любую картинку, используя imageview.

public void LoadScreen() {
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {                 
                Intent i = new Intent(SplashScreenActivity.this, AgilanbuGameOptionsActivity.class);
                startActivity(i);
            }
        }, 2000);
    }

1

Вы можете добавить это в свой метод onCreate

new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    // going to next activity
                    Intent i=new Intent(SplashScreenActivity.this,MainActivity.class);
                    startActivity(i);
                    finish();
                }
            },time);

И инициализируйте ваше время в миллисекундах, сколько хотите ...

private  static int time=5000;

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

https://github.com/Mr-Perfectt/Splash-Screen


1

В Котлине напишите этот код: -

 Handler().postDelayed({
            val mainIntent = Intent(this@SplashActivity, LoginActivity::class.java)
            startActivity(mainIntent)
            finish()
        }, 500)

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


0

Простой код, все работает :) Простой всплеск

int secondsDelayed = 1;
    new Handler().postDelayed(new Runnable() {
        public void run() {
            startActivity(new Intent(LoginSuccessFull.this, LoginActivity.class));
            finish();
        }
    }, secondsDelayed * 1500);

0
public class SplashActivity extends Activity {

  Context ctx;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      ctx = this;
      setContentView(R.layout.activity_splash);

      Thread thread = new Thread(){
          public void run(){
              try {
                  sleep(3000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }

              Intent in = new Intent(ctx,MainActivity.class);
              startActivity(in);
              finish();
          }
      };
      thread.start();
  }
}

Это плохой пример - что произойдет, если вы выйдете из SplashActivity, нажав назад? Поток по-прежнему будет выполняться.
Марк Кин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.