81

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

Activity 可以频繁地进出前台——例如,onPause()在设备进入睡眠状态或出现对话框时调用。

我不太明白这一点。在什么情况下会发生这种情况?onPause()仅当相关对话框的上下文与要在其上显示对话框的活动不同时才调用?

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

根据上面提到的文档引用,当显示以下代码中的(或只是)onPause()时,是否应该调用我的活动方法?显示对话框时是否应该看到“onPause called”日志条目?AlertDialogDialog

但我不认为会发生这种情况。如果我正确理解了 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");
    }
}
4

7 回答 7

193

onPause()当您的活动不再位于活动堆栈的顶部时调用。Dialog本身不是Activity,所以不会替换栈顶的当前Activity,所以不会造成任何暂停。

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

于 2011-09-12T07:52:23.970 回答
13

我一直在用对话框做很多代码,包括AlertDialog你提到的,我还尝试检查onPause()对话框弹出时是否在活动上被调用,但到目前为止我的结论是活动只是继续运行,这onPause() 不叫.

不确定它是否有帮助,但至少你现在知道还有其他人经历过你正在经历的事情:-)

于 2011-09-08T09:43:33.523 回答
2

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

将活动设置为 onPause 状态 -

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

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

    例如,按下主页按钮会导致活动进入 onPause()。仍然在堆栈的顶部。

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

在图 2 中。现在 Task A 进入后台,但 Activty X 仍在堆栈顶部。如果您在此状态下覆盖 onPause() 方法

在此处输入图像描述

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

在此处输入图像描述

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

于 2014-06-07T02:34:43.560 回答
0

在我有点奇怪的经历onResume中,被调用dialog.setCanceledOnTouchOutside(true);但从onPause未被调用。

话虽如此,我认为文档可能侧重于系统对话框(例如电池电量不足)。

于 2012-02-28T09:54:47.847 回答
0

我想我记得在早期版本的 Android 生命周期中读到,当没有显示任何活动时调用 onPause。即,如果您的一些活动在弹出窗口下仍然可见,则不会调用 onPause。

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

于 2011-09-06T22:10:09.610 回答
0

@hackbot

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

一切都取决于实施......

什么是对话框?是一个由 WindowManager/// 添加到 Display 的 Window,所以它显示时的窗口位于一切之上....(Z 顺序)

什么是活动……是“事物”,它也创建了它的窗口……

当显示对话框或其窗口在现有活动之上可见时,它会覆盖部分活动窗口,因此现有活动将移至部分不可见状态,并且您将从 ActivityThread 调用 onPause()

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

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

所以当我们知道

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

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

涉及的组件:

  • 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
于 2018-07-05T20:29:58.037 回答
-4

onPause()每次当 Activity 进入后台Dialog或其他Activity进入前台时调用。这样做是为了优先考虑用户正在与之交互的事物。例如:假设您位于应用程序的主屏幕(这又是一个活动)中,则主屏幕位于foreground. 当你通过按下某个按钮进入下一个屏幕或出现一个对话框时,下一个screen/Activity/Dialog出现foreGround并且homecreen进入后台,这只是意味着homeScreen 的 onPause()方法被调用。

于 2011-09-06T10:45:04.133 回答