Android: За яких обставин діалог, що з’являється, може викликати onPause ()?


79

Фрагмент документа Android Activity (прокрутіть вниз до рядка " передній план життя ") говорить:

Діяльність часто може переходити на перший план і виходити з нього - наприклад, onPause()викликається, коли пристрій переходить у режим сну або коли з’являється діалогове вікно .

Я не зовсім цього розумію. За яких обставин це повинно статися? Викликається onPause()лише в тому випадку, якщо контекст відповідного діалогового вікна відрізняється від діяльності, поверх якої діалогове вікно має відображатися?

EDIT: Додавання зразка коду, щоб детально проілюструвати мої сумніви

Якщо йти за вищезгаданою цитатою з документа, чи слід onPause()викликати метод моєї діяльності, коли відображається AlertDialog(або просто Dialog) у наступному коді? Чи повинен я бачити запис журналу "onPause викликаний", коли відображається діалогове вікно?

Але я не бачу, щоб це сталося. І теж не повинно, якщо я правильно зрозумів життєвий цикл Android! Отже, на що тоді вказує документ?

public class LifeCycleTestActivity extends Activity {

    private static final String TAG = "LifeCycleTest";

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

        Button btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick");

                AlertDialog dialog = new AlertDialog.Builder(LifeCycleTestActivity.this).create();
                 dialog.setMessage("You Clicked on the button");
                 dialog.setTitle("Dialog!");
                 dialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                 dialog.setCancelable(true);
                 dialog.show();


                /*
                Dialog dialog = new Dialog(LifeCycleTestActivity.this);
                 dialog.setTitle("Dialog!");
                 dialog.setCancelable(true);
                 dialog.show();
                */
            }
        });        
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause() called");
        super.onPause();

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume() called");
    }
}

Відповіді:


187

onPause()викликається, коли ваша діяльність більше не знаходиться у верхній частині стеку активності. Діалог сам по собі не є активністю, тому не замінить поточну активність у верхній частині стека, тому нічого не призведе до паузи.

Однак діалогове вікно (малої літери) не потрібно реалізовувати класом Dialog. Наприклад, нерідкі випадки, коли реалізується такий засіб, який має тему діалогового вікна. У цьому випадку відображення діалогу-як-дії призведе до того, що нове " Діяльність" опиниться у верхній частині стеку, призупиняючи те, що було раніше.


8
Чудова відповідь. «Діалог як дія» мені не спало на думку. І міркування про те, що onPause()викликається лише тоді, коли діалогове вікно знаходиться у верхній частині стека, - це також пояснює, чому onPause()не викликається, навіть коли панель сповіщень опускається вниз, повністю затуляючи активність.
curioustechizen

2
@curioustechizen Тут так багато тонкощів ... Завдяки вашому запитанню (і відповіді цього дивовижного професіонала від команди Android) я швидко зміг зрозуміти, чому я спостерігаю у своєму додатку саме те, що ви спостерігали. +1.
ateiob

1
@hackbod: Так само системний діалог спричинить onPause (). Я бачу це, переглядаючи системні діалогові вікна, що стосуються дозволу на зефір!
Abat

@abat Це, мабуть, тому, що діалог Дозвіл реалізований як Діяльність із темою, встановленою на тему Діалога
curioustechizen

13

Я робив досить багато коду з діалоговими вікнами, включаючи той, про AlertDialogякий ви згадали, і я також намагався перевірити, чи onPause()викликається активність під час появи діалогового вікна, але поки що мій висновок полягає в тому, що ця активність просто продовжує працювати, і onPause() це не викликається .

Не впевнений, чи допомагає це, але принаймні ви тепер знаєте, що є й інші, хто відчуває те, що ви переживаєте :-)


Ну, насправді, якщо я правильно розумію життєвий цикл, я вважаю, що діалогове вікно НЕ ПОВИННО запускати onPause(). Отже, спостережувана поведінка відповідає очікуваному. Просто я випадково натрапив на цю інформацію, яку я цитував і до якої посилався. І це повело мене шляхом розгубленості!
curioustechizen

2

Неправильно, що активність залишається на вершині стека активності у фазі onPause.

Стан активності, щоб вона була у режимі Пауза -

  • Діяльність частково видно, наприклад, діалог про діяльність.

  • Об'єкт Activity зберігається в пам'яті, він зберігає всю інформацію про стан та членів і залишається приєднаним до диспетчера вікон.

    наприклад, натиснута кнопка «Домашня сторінка» призводить до того, що активність переходить у onPause (). Все ще у верхній частині стека.

На рис. Діяльність3 буде знищена та видалена з верхнього стеку

На рис. 2. Завдання A переходить у фоновий режим, але Activty X все ще знаходиться на вершині стека. Якщо ви перевизначите метод onPause () в цьому стані

введіть тут опис зображення

Рисунок 1. Відображення того, як кожна нова діяльність у завданні додає елемент до заднього стеку. Коли користувач натискає кнопку Назад, поточна активність знищується, а попередня активність відновлюється.

введіть тут опис зображення

Рисунок 2. Два завдання: Завдання B отримує взаємодію користувача на передньому плані, тоді як Завдання A знаходиться у фоновому режимі, чекаючи відновлення.


1
У сценарії, який ви пояснили, Activityфайл все ще знаходиться у верхній частині стека, але саме завдання пішло на другий план. В основному користувач більше не взаємодіє з вашим Activity- хтось інший Activity(або з вашого власного завдання, або з якогось іншого) вийшов на перший план. Саме цим намагається пояснити прийняту відповідь.
curioustechizen

0

Здається, я пам’ятаю, як читав у попередній версії Життєвого циклу Android, що було викликано onPause, коли жодна з дій не відображається. тобто якщо трохи вашої активності все ще видно у спливаючому вікні, onPause не буде викликаний.

Можливо, деякі інші експерти можуть поручитися за таку поведінку?


Біт про onPause()виклик, якщо нічого з цього Activityне відображається - це, як правило, правда, але не суворо. Наприклад, коли ви опускаєте панель сповіщень так, щоб вона повністю затуляла вашу активність, onPause()все одно не викликається.
curioustechizen

0

У моєму трохи дивному досвіді onResumeтелефонують, dialog.setCanceledOnTouchOutside(true);але onPauseніколи не телефонують.

З огляду на це, я думаю, що документація може бути зосереджена на діалогах системи (наприклад, низький рівень заряду акумулятора).


0

@hackbot

onPause () викликається, коли ваша діяльність більше не знаходиться у верхній частині стеку Activity>. Діалог сам по собі не є активністю, тому не замінить поточну> активність у верхній частині стека, тому нічого не призведе до паузи.

все залежить від реалізації ...

що таке діалог? - це вікно, додане до Відображення WindowManager ///, тому вікно, коли воно відображається, знаходиться поверх усього .... (порядок Z)

що таке діяльність ... це "річ", яка також створює своє вікно ....

коли діалогове вікно відображається або його вікно відображається поверх існуючої діяльності, воно замінює частково вікно активності, тому існуюча активність переходить у частково невидимий стан, і ви отримаєте виклик onPause () з ActivityThread .

але, щоб бути впевненим, нам також потрібно розглянути тут одну думку ...

стан вікна, якщо це автономне вікно, що відображається зверху, або це дочірнє вікно, а батько - вікно активності. ...

так коли ми знаємо

  • вікно. LayoutParams (ПРАПОРИ) , які ми використовуємо , щоб додати
  • і що IBinder використовується для відображення Вікна

ми покажемо, як поводитиметься діяльність, коли вікна відображатимуться одне над одним .. оскільки кожен виндоу має зворотні дзвінки вони використовуються діяльністю або діалогом для управління своїми станами ...

задіяні компоненти:

  • android.os.IBinder

  • android.view.Window

  • android.view.Window.Callback

  • android.view.WindowManager

  • android.view.WindowManager.LayoutParams

  • android.view.Display

доречі:

якщо ви хочете знати вікна на екрані [застосовне лише до процесу, яким ви володієте - оскільки вікно належить процесу, а це тести в пісочниці - кожен процес є окремою JVM, строго кажучи "ART"], ви можете скористатися перезаписом, див .:

  • android.view.WindowManagerImpl
  • android.view.WindowManagerGlobal

-4

onPause()називається кожен раз, коли дія переходить у фоновий режим Dialogабо інше Activityвиходить на перший план. Це робиться для того, щоб надати першочергове значення тому, з чим взаємодіє користувач. наприклад: припустимо, що ви знаходитесь на головному екрані (що, в свою чергу, є діяльністю) програми, головний екран, як кажуть, знаходиться foreground. і коли ви переходите до наступного екрана, натискаючи якусь кнопку або з'являється діалогове вікно, наступне screen/Activity/Dialogприходить foreGroundі головний екран переходить до backGround, що просто означає , що onPause() метод homeScreen викликаний.


Ну, випадок, коли інша діяльність виходить на перший план, очевидний. Мене бентежить твердження документа, щоonPause() викликається при появі діалогового вікна. Я відредагував своє запитання кодом, пояснюючи, що, на мою думку, стверджує документ, але я не бачу, щоб це сталося.
curioustechizen

@ techie.curious .. так, можливо, ти маєш рацію. це відбувається лише з переходом Activity, а не тоді, коли створюється діалогове вікно .. я перевірив це зараз.
ngesh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.