Android Activity 中的 onPause() 和 onStop()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11387258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
onPause() and onStop() in Activity
提问by Stephan Doliov
I am new to Android development and I am still not able to understand the onPause()
and onStop()
methods in an activity.
我是 Android 开发的新手,我仍然无法理解活动中的onPause()
和onStop()
方法。
In my app, I have a static class that I name Counter, and it keeps the state of variables in memory for the app. My app runs fine in the emulator. What I was trying to test was differential behavior of onPause()
versus onStop()
.
在我的应用程序中,我有一个名为 Counter 的静态类,它将变量的状态保存在应用程序的内存中。我的应用程序在模拟器中运行良好。我试图测试的是onPause()
vs 的不同行为onStop()
。
For onPause
, I wanted the values stored in the Counter class's members retained, whereas calling onStop()
I wanted the counter values reset to zero. So I override onStop()
and set the variables inside the counter class to zero. However, in the emulator, I cannot seem to get the app in the Paused state. In the emulator, I open my app, exercise it. Then I hit the home button (not the back button) of the emulator, and launch another app, believing that this would mimic onPause()
activity. However, the emulator does not appear to honor this (I am using an armeabi v7a emulator), it seems to always be calling onStop()
because my counter values all go back to zero, per my override in onStop()
. Is this inherent to the emulator or am I doing something wrong to get my activity into the paused state?
对于onPause
,我希望保留 Counter 类成员中存储的值,而调用onStop()
我希望计数器值重置为零。所以我覆盖onStop()
并将计数器类中的变量设置为零。但是,在模拟器中,我似乎无法使应用程序处于暂停状态。在模拟器中,我打开我的应用程序,运行它。然后我点击模拟器的主页按钮(不是后退按钮),并启动另一个应用程序,相信这会模仿onPause()
活动。但是,模拟器似乎并不尊重这一点(我使用的是 armeabi v7a 模拟器),它似乎总是在调用,onStop()
因为根据我在onStop()
. 这是模拟器固有的还是我做错了什么让我的活动进入暂停状态?
回答by Alex Lockwood
I'm not sure which emulator you are testing with, but onPause
is the one method that is alwaysguaranteed to be called when your Activity
loses focus (and I say alwaysbecause on some devices, specifically those running Android 3.2+, onStop
is not always guaranteed to be called before the Activity
is destroyed).
我不确定您正在使用哪个模拟器进行测试,但这onPause
是一种在您失去焦点时始终保证会被调用的方法Activity
(我总是这样说,因为在某些设备上,特别是那些运行 Android 3.2+ 的设备,onStop
并不总是保证会调用)在Activity
销毁之前调用)。
A nice way to understand the Activity
lifecycle for beginners is to litter your overriden methods with Log
s. For example:
Activity
对于初学者来说,理解生命周期的一个好方法是用Log
s乱扔覆盖的方法。例如:
public class SampleActivity extends Activity {
/**
* A string constant to use in calls to the "log" methods. Its
* value is often given by the name of the class, as this will
* allow you to easily determine where log methods are coming
* from when you analyze your logcat output.
*/
private static final String TAG = "SampleActivity";
/**
* Toggle this boolean constant's value to turn on/off logging
* within the class.
*/
private static final boolean VERBOSE = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (VERBOSE) Log.v(TAG, "+++ ON CREATE +++");
}
@Override
public void onStart() {
super.onStart();
if (VERBOSE) Log.v(TAG, "++ ON START ++");
}
@Override
public void onResume() {
super.onResume();
if (VERBOSE) Log.v(TAG, "+ ON RESUME +");
}
@Override
public void onPause() {
super.onPause();
if (VERBOSE) Log.v(TAG, "- ON PAUSE -");
}
@Override
public void onStop() {
super.onStop();
if (VERBOSE) Log.v(TAG, "-- ON STOP --");
}
@Override
public void onDestroy() {
super.onDestroy();
if (VERBOSE) Log.v(TAG, "- ON DESTROY -");
}
}
回答by Julien Rousseau
I know your question was 6 months ago but in case someone else stumbles on this question:
我知道你的问题是 6 个月前的,但以防万一其他人偶然发现这个问题:
am I doing something wrong to get my activity into the paused state.
我做错了什么让我的活动进入暂停状态。
Yes, you are. This:
是的,你是。这个:
I hit the home button (not the back button) of the emulator, and launch another app, believing that this would mimic onPause() activity.
我点击模拟器的主页按钮(不是后退按钮),然后启动另一个应用程序,相信这会模仿 onPause() 活动。
Hitting the home button will indeed call the onPause()
method but because the home button makes your activity no longer visible it will then call the onStop()
method (like patriot & milter mentioned).
点击主页按钮确实会调用该onPause()
方法,但由于主页按钮使您的活动不再可见,因此它将调用该onStop()
方法(如提到的 patriot 和 milter)。
As per the Activities developer reference (http://developer.android.com/guide/components/activities.html) you can display a dialog or simply put the device to sleep.
根据活动开发人员参考 ( http://developer.android.com/guide/components/activities.html),您可以显示一个对话框或简单地将设备置于睡眠状态。
Alternatively, you call an activity that will only partially obstruct the calling activity. So call an activity that creates a window with a view of size:
或者,您调用的活动只会部分阻碍调用活动。因此,调用一个创建具有大小视图的窗口的活动:
android:layout_width="100dp"
android:layout_height="100dp"
Which doesn't cover the entire screen, thus leaving the calling activity behind partially visible, thus calling only calling activity's onPause()
method.
这不会覆盖整个屏幕,从而使调用 Activity 部分可见,从而仅调用调用 Activity 的onPause()
方法。
Clone that activity so that both view sizes are "match_parent" instead of "100dp" and call it and both the onPause()
and onStop()
methods of the calling activity will be called because the calling activity won't be visible.
克隆该活动,以便两个视图大小都是“match_parent”而不是“100dp”并调用它,onPause()
并且onStop()
调用活动的和方法都将被调用,因为调用活动将不可见。
There can be exceptions of course, like if the called activity causes an app crash in either of its onCreate()
, onStart()
or onResume()
then the onStop()
of the calling activity will not be called, obviously, I'm just talking about the general case here.
有当然可以例外,如果被叫活动引起像一个应用程序崩溃其任的onCreate()
,onStart()
或onResume()
则onStop()
调用活动将不会被调用,很明显,我只是在谈论一般情况下在这里。
回答by patriot
The differences between when onPause() and onStop() are called can be pretty subtle. However, as explained here, onPause() will usually get executed when another activitytakes focus (maybe as a pop up, or transparent window) while the current activity is still running. If you navigate away from the app completely (for example, by hitting the home button), the activity is no longer visible and the system may execute onStop(). I only say may because, as Alex mentioned, there are some cases where onStop doesn't get called before the Activity is destroyed.
调用 onPause() 和 onStop() 之间的差异可能非常微妙。但是,正如这里所解释的,当当前活动仍在运行时,当另一个活动获得焦点(可能作为弹出窗口或透明窗口)时,通常会执行 onPause() 。如果您完全离开应用程序(例如,通过点击主页按钮),则 Activity 不再可见,系统可能会执行 onStop()。我只说可能是因为,正如 Alex 所提到的,在某些情况下,在 Activity 被销毁之前没有调用 onStop。
回答by nik
onPause():
暂停():
"If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations."
“如果一个 Activity 失去焦点但仍然可见(也就是说,一个新的非全尺寸或透明的 Activity 在你的 Activity 顶部有焦点),它就会被暂停。暂停的 Activity 是完全活跃的(它保持所有状态和成员信息并保持附加到窗口管理器),但在内存极低的情况下可能会被系统杀死。”
onStop():
停止():
"If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere."
“如果一个活动被另一个活动完全遮挡,它就会停止。它仍然保留所有状态和成员信息,但是,它不再对用户可见,因此它的窗口被隐藏,并且经常被系统在内存时杀死其他地方需要。”
Taken from android reference activity class: http://developer.android.com/reference/android/app/Activity.html
取自 android 参考活动类:http: //developer.android.com/reference/android/app/Activity.html
回答by Tamás Szincsák
If you are emulating Android 4.x you can control how the system handles background activities using Settings -> Developer Options -> Don't keep activities and Background process limit. For older versions there is an app called Dev Tools which contains the same settings. However, on low memory conditions the system can disregard those settings and terminate your application. Increasing the amount of memory assigned to the emulator might help.
如果您正在模拟 Android 4.x,您可以使用设置 -> 开发人员选项 -> 不保留活动和后台进程限制来控制系统处理后台活动的方式。对于旧版本,有一个名为 Dev Tools 的应用程序,其中包含相同的设置。但是,在内存不足的情况下,系统可以忽略这些设置并终止您的应用程序。增加分配给模拟器的内存量可能会有所帮助。
Also, if you are re-launching your app from Eclipse, it will kill the previous process instead of gracefully terminating it.
此外,如果您从 Eclipse 重新启动您的应用程序,它将终止之前的进程而不是正常终止它。
回答by Gilson
I agree with milter!
我同意米尔特!
onPause():
暂停():
"If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations."
“如果一个 Activity 失去焦点但仍然可见(也就是说,一个新的非全尺寸或透明的 Activity 在你的 Activity 顶部有焦点),它就会被暂停。暂停的 Activity 是完全活跃的(它保持所有状态和成员信息并保持附加到窗口管理器),但在内存极低的情况下可能会被系统杀死。”
If you swap applications without pressing Back (press and hold HOME) then the OS is going to call onPause. When you return to your activity (press and hold HOME again) in onResume you should have all of your private variables preserved. But you can't control the user, right?!
如果您在不按 Back(按住 HOME)的情况下交换应用程序,则操作系统将调用 onPause。当您在 onResume 中返回您的活动(再次按住 HOME)时,您应该保留所有私有变量。但是你不能控制用户,对吧?!
if you anticipate that the user is going to leave your app and the OS calls your onStop you better save your data if you intend to resume where you left-off.
如果您预计用户将离开您的应用程序并且操作系统调用您的 onStop 您最好保存您的数据,如果您打算从您离开的地方继续。
I have a Timer also, I need to save the elapsed time so when the user returns I can restore the data. here is my example to save:
我也有一个计时器,我需要保存经过的时间,以便当用户返回时我可以恢复数据。这是我要保存的示例:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putLong("elapsedTime", elapsedTime);
// etc.
}
And my code to restore:
还有我要恢复的代码:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
elapsedTime = savedInstanceState.getLong("elapsedTime");
}
Place these methods inside of your class and you are good to go. Keep in mind that the string "elapsedTime" in my case is a KEY to the system and it must be unique. Use unique strings for each piece of data that you would like to save. For example "startClock", "ClockTextColor", etc...
将这些方法放在您的类中,您就可以开始使用了。请记住,在我的情况下,字符串“elapsedTime”是系统的关键,它必须是唯一的。对要保存的每条数据使用唯一的字符串。例如“startClock”、“ClockTextColor”等...