Android:在什么情况下出现对话框会导致onPause()被调用?


77

Android Activities文档中的一个片段(向下滚动到“前台寿命”行)说:

活动可能会频繁地进入和退出前台,例如,onPause()当设备进入睡眠状态或出现对话框时,就会调用该活动。

我不太明白。在什么情况下会发生这种情况?被onPause()称为仅如果有问题的对话的上下文是从顶部其活性的对话框将显示不同?

编辑:添加代码示例以详细说明我的疑问

按照文档中的上述引用,onPause()当显示以下代码中的AlertDialog(或仅显示Dialog)我的活动的方法是否应该被调用?显示对话框时,我是否应该看到“ onPause named”日志条目?

但我看不到这种情况。如果我正确理解了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");
    }
}

Answers:


186

onPause()当您的活动不再位于活动堆栈的顶部时,将调用。对话框本身不是活动,因此不会替换堆栈顶部的当前活动,因此不会导致任何暂停。

但是,对话框(小写)不需要由Dialog类实现。例如,用一个Activity来实现其主题设置为对话框主题的情况并不少见。在这种情况下,显示“活动为对话框”将使新的活动位于堆栈的顶部,并暂停以前的活动。


8
好答案。对我来说,“对话即活动”并没有发生。以及onPause()仅当对话框位于堆栈顶部时才调用的理由-这也解释了为什么onPause()即使通知栏被拉到最底端也不会调用该原因,从而完全掩盖了活动。
curioustechizen 2011年

2
@curioustechizen这里有很多微妙的东西...多亏您的问题(以及来自Android团队的这位出色专业人士的回答),我已经能够快速理解为什么我在应用程序中观察到的正是您所观察到的。+1。
ateiob 2012年

1
@hackbod:系统对话框也会导致onPause()。在查看与棉花糖权限相关的系统对话框时,我看到了这一点!
2016年

@abat这可能是因为“权限”对话框被实现为“活动”,其主题设置为“对话框”
curioustechizen 2016年

13

我已经使用对话框做了很多代码,包括AlertDialog您提到的代码,并且我还尝试检查onPause()对话框弹出时是否在活动上调用了该方法,但是到目前为止,我的结论是该活动仅仅是保持运行,这onPause() 没有被调用

不确定是否有帮助,但是至少您现在知道有些人正在经历您的经历:-)


好吧,实际上,如果我正确理解了生命周期,我相信对话框一定不会触发onPause()。因此,观察到的行为与预期的一致。只是我偶然偶然发现了我引用并链接到的这些信息。这使我走上了困惑的道路!
curioustechizen

2

错误的是,活动在onPause阶段不再保留在活动堆栈的顶部。

将活动设置为暂停状态-

  • 活动部分可见,例如活动对话框。

  • Activity对象保留在内存中,它维护所有状态和成员信息,并保持与窗口管理器的连接。

    例如,按下“主页”按钮会使活动进入onPause()。仍在堆栈顶部。

在图1中。Activity3将被销毁并从顶部堆栈中移除

在图2中,现在任务A进入后台,但Activty X仍位于堆栈顶部。如果在此状态下重写onPause()方法

在此处输入图片说明

图1.任务中每个新活动如何将项目添加到后台堆栈的表示。当用户按下“后退”按钮时,当前活动将被销毁并且上一个活动将恢复。

在此处输入图片说明

图2.两个任务:任务B在前台接收用户交互,而任务A在后台等待恢复。


1
在您所解释的场景中,Activity仍然位于堆栈的顶部,但是任务本身已经进入后台。基本上,用户不再与您进行交互Activity-其他Activity(无论是您自己的任务还是其他)都位于最前面。那就是被接受的答案试图解释的。
curioustechizen 2014年

0

我想我记得在Android Lifecycle的较早版本中读过,没有活动显示时调用了onPause。即,如果您的活动的一部分仍然在弹出窗口下可见,则不会调用onPause。

也许其他一些专家可以证明这种行为?


onPause()如果没有Activity显示任何有关被调用的位-通常是正确的,但并非严格如此。例如,当您下拉通知栏以使其完全遮盖您的活动时,onPause()仍然不会被调用。
curioustechizen

0

在我有点奇怪的经历中,onResume有人打电话给我,dialog.setCanceledOnTouchOutside(true);onPause从未有人打电话给我。

话虽如此,我认为文档可能集中在系统对话框上(例如电池电量低)。


0

@hackbot

当您的活动不再位于活动>堆栈顶部时,将调用onPause()。对话框本身不是活动,因此不会替换堆栈顶部的当前>活动,因此不会导致任何暂停。

一切都取决于实施...

什么是对话框?是由WindowManager ///添加到“显示”的一个窗口,因此显示时的窗口位于所有内容的顶部....(Z顺序)

是什么活动......是“东西”这也创造了其窗口....

当显示对话框或它的窗口在现有活动的顶部可见时,它将覆盖活动窗口的一部分,因此现有活动将变为部分不可见状态,您将从ActivityThread调用onPause()

但可以肯定的是,我们还需要在这里考虑一个想法...

窗口的状态,如果是在顶部显示的独立窗口,或者是子窗口,而父窗口是活动窗口。...

所以当我们知道

  • 我们用来添加的Window.LayoutParams(FLAGS)
  • 以及用于窗口显示的IBinder

我们将了解当窗口相互显示时活动的行为方式..每个窗口都有一个回调,活动或对话框将使用它们来管理其状态...

涉及的组件:

  • android.os.IBinder

  • android.view.Window

  • android.view.Window.Callback

  • android.view.WindowManager

  • android.view.WindowManager.LayoutParams

  • android.view.Display

顺便说一句:

如果您想知道屏幕上的窗口[仅适用于您自己的进程-窗口属于进程,而它们属于沙盒-每个进程都是一个单独的JVM,严格说“ ART”],则可以使用replection:

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

-4

onPause()每当Activity进入后台,Dialog或其他Activity到场时被调用。这样做是为了使用户与之交互的事物具有第一优先权。例如:假设您在应用程序的屏幕中(这又是一个活动),则称主屏幕在中foreground。当您按下某个按钮进入下一个屏幕或出现对话框时,下一个screen/Activity/Dialog出现foreGroundhomecreen进入backGround,这仅意味着homeScreen的 onPause()方法被调用。


好吧,另一个Activity成为前台的情况很明显。我对onPause()出现对话框时调用的文档声明感到困惑。我已经用解释了我认为文档所声称的代码的代码编辑了我的问题,但是我看不到有什么事情发生。
curioustechizen

@ techie.curious..yeah也许你是正确的。它仅在活动转换时发生,而在创建对话框时则不发生。
ngesh 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.