Android Activites的onPause()和onStop()有什么区别?


149

http://developer.android.com/reference/android/app/Activity.html上的 android文档中,将调用'Activity进入前台' onPause(),而调用'Activity不再可见' onStop()

“活动进入前台”与“活动不再可见”一样吗?你能告诉我它们有什么区别吗?


17
+1是一个很好的问题。此外,paused活动是完全活动的(它维护所有状态和成员信息,并仍附加到窗口管理器中)。甲stopped的活性也保留了所有状态和成员信息,但不再附着到window manager
ateiob 2012年

Answers:


107

不,如果某个活动进入了前台,那并不一定意味着其他活动是完全不可见的。考虑以下情况:

主题为Theme.Dialog的活动

在这里,我们同时看到两个活动。带有该字段的第一个活动被另一个活动遮盖了,用户无法再与其交互。但是,它仍然可见,并具有所有结果。

这就提出了一个问题,即哪些活动被认为是完全不透明的并且覆盖整个屏幕,而哪些不是。该决定基于包含活动的窗口。如果窗口具有标志windowIsFloatingwindowIsTranslucent,则认为该活动不会使基础内容不可见,否则它将onStop()被调用。相关代码可以在以下位置找到com.android.server.am.ActivityRecord

fullscreen = ent != null && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsFloating, false)
        && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsTranslucent, false);

10
+1是一个很好的解释,着眼于部分可见性与总体可见性。知道让Android在onPause()和之间做出决定的屏幕阈值百分比会很有趣onStop()。是100%吗?如果上一个活动中只有一个像素可见,它仍然onPause()吗?
ateiob 2012年

3
@ateiob在任何地方都没有说,但我认为是。但是,这通常很明显,因为大多数无法充满整个屏幕的活动仅使用系统提供的对话框样式之一。
马尔科姆

1
很奇怪,但是在onPause()显示对话框时根本没有调用我的应用程序。onPause()仅当我按下屏幕按钮时才会调用。这怎么可能?
ateiob 2012年

这应该是正确的答案。顺便说一句,前景是对话还是活动?
GMsoF 2012年

3
@GMsoF活动。这就是要点:并不是每个对话框实际上都是一个对话框。您可以使活动看起来像对话框,因此它实际上小于整个屏幕。
马尔科姆2012年

38

如果您仍然可以看到它的任何部分(Activity进入前景或者不占据整个屏幕,或者有点透明),onPause()则会被调用。如果看不到它的任何部分,onStop()将被调用。

例如,对话框**可能不会覆盖整个上一个对话框,Activity这将是时候onPause()进行调用了。

**我在这里不是指Android对话框,而是指弹出的内容仅掩盖了部分用户屏幕的概念。添加此注释是为了根据以下@GMsoF的注释进行澄清


33
没有。这是误导。显示的对话框将不会调用onPause(),因为对话框使用当前活动的上下文,请考虑活动是否活动。
GMsoF 2012年

6
@GMsoF听起来就像当我说对话框时,您以为是我的意思Dialog,就像在Android类中一样。不过,我所得到的是部分掩盖了第一个事实,Activity以说明所有新的事物Activity并不需要完全掩盖前一个思想。
nicholas.hauschild 2012年

11

位于前台意味着该活动具有输入焦点。例如,活动可以显示,但被具有焦点的对话框部分遮盖。在这种情况下,onPause()将被调用,但不会被调用onStop()。对话框消失后,onResume()将调用活动的方法(但不会调用onStart())。


5
对话可能会引起误解。让我们从此活动的主UI线程弹出一个警告对话框,在这种情况下将不会调用onPause()。仅当从其他活动或其他应用程序弹出此对话框时。
Sam003

1
@致胜-我同意你的评论。我只是在解释“活动” 指南主题onPause()当设备进入睡眠状态或出现对话框时被调用”。不过,正如该线程所指出的那样,对话并不一定意味着活动已暂停(尽管它是用于显示为对话框活动)。
泰德·霍普

9

实际上,应该考虑“ onPause()”“ onPause()+ onStop()” 之间区别

每当发生新的活动并占用屏幕的某些部分空间时。因此,您先前运行的活动在某种程度上仍然可见。在这种情况下,先前运行的活动不会被推送到Back Stack。因此,这里仅调用onPause()方法

另一方面,如果发生了一些新的活动,并且该活动占据了全屏,则以前运行的活动将消失。在这种情况下,您先前运行的活动将移至Back Stack。在这里,调用了onPause()+ onStop()。

总结

onPause() -屏幕被其他新活动部分覆盖。该活动未移至“后退堆栈”。

onPause()+ onStop() -屏幕被其他新活动完全覆盖。该活动将移至“后退堆栈”。

了解更多有关Back Stack的信息


0

简而言之:

onStop()当显示另一个活动时,将调用先前活动生命周期方法的“活动”。当活动顶部有“对话”时,将onPause()调用该对话。

注意:活动是填充整个屏幕的那些组件。

注意:对话不是活动,因为对话没有完全填满屏幕。


0

我在使用onPause和onStop方法时遇到了许多问题,因此我将清除遇到的三种情况:
1.当您单击最近的应用程序按钮时,未调用任何生命周期方法,但使用hasFocus值调用了onWindowFocusChanged(boolean hasFocus)通过为假。在5之前的android版本中,按最近的应用程序按钮时会调用onPause方法。

2.当活动上方出现类似活动的弹出窗口时(如Malcolm所述),将调用onPause按钮。如果调用占据整个屏幕的新活动,则在先前活动上调用onStop。Android 权限对话框还会导致您的活动调用onPause。

3。如果屏幕因您的活动而超时,则会调用onPause。一段时间后,如果您不打开屏幕,则会调用onStop。

ateiob提到的另一件重要的事情就是答案

暂停的活动是完全活动的(它维护所有状态和成员信息,并仍附加到窗口管理器中)。停止的活动还保留所有状态和成员信息,但不再附加到窗口管理器


希望能帮助到你。


0

每当新的活动开始上一个活动的 onPause在任何情况下都将挑衅地调用。

实际上会有两种情况:

1-先前活动的一部分可见或新活动透明:仅 onPause会被调用。

2-先前活动完全被新活动覆盖:两者onPauseonStop都将被称为

----很高兴指出一些注意事项:

注意1:如果对话框在活动NONE onPause或的顶部开始,onStop则将被调用。

注意2:如果其活动的主题设置为对话框,则其行为将与普通活动类似。

注意3:显然是一个系统对话框,例如权限对话框,因为棉花糖会导致onPause


-5

是的,我尝试理解,可以在下面进行解释:

有2个活动:ActivityA和ActivityB

public class ActivityA extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
}

private void initialize() {
    Log.i("Activity A", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity A", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity A", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity A", "onResume");
}

@Override
protected void onPause() {
    super.onPause();
    Log.i("Activity A", "onPause");
}

@Override
protected void onStop() {
    super.onStop();
    Log.i("Activity A", "onStop");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i("Activity A", "onDestroy");
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        Intent activityB = new Intent(this, ActivityB.class);
        startActivity(activityB);
        break;
    default:
        break;
    }
}

这是活动B。在代码中关注我的评论

public class ActivityB extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
    // if call finish() here, activityA will don't stop, just pause
    // Activity A will call onStop() when Activity B call onStart() method
    finish();
}

private void initialize() {
    Log.i("Activity B", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity B", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity B", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity B", "onResume");
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        finish();
        break;
    default:
        break;
    }
}
}

我希望这很明显


总是,尝试解释这是有道理的
Alexander Zaldostanov
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.