Android:什么情况下出现Dialog会导致onPause()被调用?
Android Activities 文档的片段(向下滚动到“ 前台生命周期”行)说:
一个 Activity 可以频繁地进出前台,例如 例如,当设备进入睡眠状态或当 出现对话框。
我不太明白这一点。什么情况下会发生这种情况?仅当相关对话框的上下文与要在其上显示对话框的活动不同时才调用 onPause()
吗?
编辑:添加代码示例来详细说明我的疑问根据
上述文档中的引用,当 AlertDialog
(或者只是下面代码中的 Dialog
) 会显示吗?显示对话框时我应该看到“onPause Called”日志条目吗?
但我不认为这种情况会发生。如果我正确理解 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");
}
}
A snippet from the Android Activities document(scroll down to the "foreground lifetime" line) says :
An activity can frequently transition in and out of the foreground—for
example,onPause()
is called when the device goes to sleep or when a
dialog appears.
I don't quite understand this. Under what circumstances should this happen? Is onPause()
called only if the context of the dialog in question is different from the activity on top of which the dialog is to be displayed?
EDIT: Adding code sample to illustrate my doubt in detail
Going by the above-mentioned quote from document, should my activity's onPause()
method get called when the AlertDialog
(or just the Dialog
) in the following code gets displayed? Should I see the "onPause called" log entry when the dialog is displayed?
But I don't see that happen. And it shouldn't either, if I have understood the Android life cycle correctly! So, what's the document pointing at then?
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");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
当您的 Activity 不再位于 Activity 堆栈顶部时,将调用
onPause()
。对话框本身不是活动,因此不会替换堆栈顶部的当前活动,因此不会导致任何暂停。然而,对话框(小写)不需要由 Dialog 类实现。例如,使用主题设置为对话框主题的活动来实现这一情况并不少见。在这种情况下,显示dialog-as-an-Activity将导致新的Activity位于堆栈顶部,暂停之前的活动。
onPause()
is called when your activity is no longer at the top of the activity stack. A Dialog by itself is not an Activity, so will not replace the current Activity at the top of the stack, so will not cause anything to pause.A dialog (lower-case) does not need to be implemented by a Dialog class, however. For example, it is not uncommon to implement one with an Activity whose theme is set to that of a dialog. In this case, displaying the dialog-as-an-Activity will cause the new Activity to be on the top of the stack, pausing what previously was there.
我已经用对话框编写了很多代码,包括您提到的
AlertDialog
,并且我还尝试检查是否正在调用onPause()
对话框弹出时的活动,但到目前为止我的结论是该活动只是继续运行并且onPause()
没有被调用。不确定这是否有帮助,但至少您现在知道还有其他人经历过您所经历的事情:-)
I've been doing quite a lot of code with dialogs, including the
AlertDialog
that you mention, and I've also tried to check ifonPause()
is being called on the activity when the dialog pops up, but thus far my conclusion is that the activity simply keeps running and thatonPause()
is not called.Not sure if it helps, but at least you now know that there are others who experience what you're experiencing :-)
在 onPause 阶段,活动不再位于活动堆栈的顶部,这是错误的。
将活动设置为 onPause 状态 -
活动部分可见,例如活动上的对话框。
Activity 对象保留在内存中,它维护所有状态和成员信息,并保持附加到窗口管理器。
例如按下主页按钮会导致活动进入 onPause()。仍然位于堆栈顶部。
在图 1 中。Activity3 将被销毁并从顶部堆栈中删除。
在图 2 中。现在任务 A 转到后台,但 Activty X 仍然在堆栈顶部。如果您在该状态中覆盖 onPause() 方法
图 1. 表示每个新活动如何在任务将一个项目添加到返回堆栈。当用户按下“后退”按钮时,当前活动将被销毁,并恢复上一个活动。
图 2. 两个任务:任务 B 在前台接收用户交互,而任务 A 在后台,等待恢复。
Its wrong that activity remains no longer at top of activity stack in onPause phase.
Condition an activity to be onPause state -
Activity partially visible e.g. dialog on activity.
The Activity object is retained in memory, it maintains all state and member information, and remains attached to the window manager.
e.g Home button pressed causes activity to go in onPause(). Still at top of stack.
In fig 1. Activity3 will be destroyed and removed from top stack
In fig 2. Now Task A goes to background but Activty X still on top of stack . If you override onPause() method int this state
Figure 1. A representation of how each new activity in a task adds an item to the back stack. When the user presses the Back button, the current activity is destroyed and the previous activity resumes.
Figure 2. Two tasks: Task B receives user interaction in the foreground, while Task A is in the background, waiting to be resumed.
我想我记得在 Android 生命周期的早期版本中读过,当没有显示任何 Activity 时,会调用 onPause。即,如果您的一些活动在弹出窗口下仍然可见,则不会调用 onPause。
也许其他一些专家可以为这种行为提供担保?
I think I remember reading in an earlier version of the Android Lifecycle that onPause was called when none of the activity is on display. i.e. if a bit of your activity is still visible under a popup, onPause will not be called.
Maybe some other experts can vouch for this behavior?
在我有点奇怪的经历中,
onResume
被dialog.setCanceledOnTouchOutside(true);
调用,但onPause
永远不会被调用。话虽这么说,我认为文档可能会重点关注系统对话框(例如电池电量低)。
In my slightly weird experience
onResume
gets called withdialog.setCanceledOnTouchOutside(true);
butonPause
never gets called.That being said, I think the documentation might focus on system dialogs (e.g. low on battery).
@hackbot
一切都取决于实现...
什么是对话框?是一个由WindowManager添加到Display中的Window ///
因此,当它显示时,窗口位于所有内容之上......(Z顺序)
什么是活动......是也创建其窗口的“事物”......
当显示对话框时或者它的窗口在现有活动之上可见,然后它会覆盖部分活动窗口,因此现有活动将移至部分不可见状态,并且您将从 ActivityThread 调用 onPause()。
但可以肯定的是,我们还需要在这里考虑一个想法...
窗口的状态是否是一个显示在顶部的独立窗口,或者它是一个子窗口,并且它的父窗口是一个活动窗口。...
所以当我们知道
我们将知道当 windows 时 Activity 将如何表现相互显示......因为每个窗口都有一个回调,它们由活动或对话框使用来管理其状态...
涉及的组件:
android.os.IBinder
android.view.Window
android.view.Window.Callback
android.view.WindowManager
android.view.WindowManager.LayoutParams
android.view.Display
顺便说一句:
如果你想知道屏幕上的窗口[仅适用于您拥有的进程 - 因为窗口属于进程并且这些进程是沙盒的 - 每个进程都是一个单独的 JVM 严格地说“ART”]您可以使用 replection 请参阅:
@hackbot
everything depends on implementation...
what is a Dialog ? is a Window added to Display by WindowManager///
so the window when it shows is on top of everything .... (Z order)
what is activity... is "thing" that also creates its window....
when a dialog is shown or it's window comes visible on top of an existing activity, then it overrides partial the activity window so existing activity will move to partially invisible state and you will get call to onPause() from ActivityThread.
but to be sure we also need to consider here a one think...
the state of window if is a standalone window shown on top or it is a child window and a parent of it is a activity window....
so when we know
we will khow how the activity will behave when windows are shown each over other .. as each winndow has a callbacks they are used by activity or dialog to manage their states...
involved components:
android.os.IBinder
android.view.Window
android.view.Window.Callback
android.view.WindowManager
android.view.WindowManager.LayoutParams
android.view.Display
btw:
if you want to know the windows on screen [ applicable only for the process you own - as window belongs to process and those are Sandboxed - each processs is a separate JVM strictly saying "ART" ] you can use a replection see :
每当 Activity 进入后台且
Dialog
或其他Activity
进入前台时,都会调用onPause()
。这样做是为了优先考虑用户正在交互的事物。例如:假设您位于应用程序的主屏幕(这又是一个活动),则称主屏幕位于前台
。当您通过按某个按钮进入下一个屏幕或出现对话框时,下一个屏幕/活动/对话框将出现在前台,而主屏幕将转到backGround,这仅意味着 homeScreen 的onPause()
方法被调用。onPause()
is called every Time when an Activity goes background andDialog
or otherActivity
comes foreGround. This is done to give first priority to something with which the user is interacting. e.g: assume you are in homescreen (which in turn is an activity) of an application, the homescreen is said to be inforeground
. and when you go to next screen by pressing some button or a dialog appears the nextscreen/Activity/Dialog
comes toforeGround
and homecreen goes to backGround, which just means homeScreen'sonPause()
method got called.