简体   繁体   English

Activity中的onPause()和onStop()

[英]onPause() and onStop() in Activity

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. 在我的应用程序中,我有一个静态类,我将其命名为Counter,它将变量的状态保存在应用程序的内存中。 My app runs fine in the emulator. 我的应用程序在模拟器中运行良好。 What I was trying to test was differential behavior of onPause() versus onStop() . 我试图测试的是onPause()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. 对于onPause ,我希望保留Counter类成员中存储的值,而调用onStop()我希望计数器值重置为零。 So I override onStop() and set the variables inside the counter class to zero. 所以我重写onStop()并将计数器类中的变量设置为零。 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. 然后我点击模拟器的主页按钮(而不是后退按钮),启动另一个应用程序,相信这会模仿onPause()活动。 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() . 但是,模拟器似乎没有遵守这一点(我使用的是armeabi v7a模拟器),它似乎总是调用onStop()因为我的计数器值全部回到零,按照onStop()覆盖。 Is this inherent to the emulator or am I doing something wrong to get my activity into the paused state? 这是模拟器固有的,还是我做错了让我的活动进入暂停状态?

I'm not sure which emulator you are testing with, but onPause is the one method that is always guaranteed to be called when your Activity loses focus (and I say always because 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. 一个很好的方式,了解Activity初学者的生命周期是垃圾你重写的方法与Log秒。 For example: 例如:

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 -");
    }
}

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()方法(如提到的爱国者和米尔特)。

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. 根据Activities开发人员参考( 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. 这不会覆盖整个屏幕,从而使调用活动部分可见,因此只调用调用活动的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()将不会被调用,显然,我是这里只谈一般情况。

The differences between when onPause() and onStop() are called can be pretty subtle. 调用onPause()和onStop()之间的差异可能非常微妙。 However, as explained here , onPause() will usually get executed when another activity takes focus (maybe as a pop up, or transparent window) while the current activity is still running. 但是,正如此处所解释的那样,当当前活动仍在运行时,onPause()通常会在另一个活动获得焦点(可能是弹出窗口或透明窗口)时执行。 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(). 如果您完全离开应用程序(例如,通过点击主页按钮),活动将不再可见,系统可能会执行onStop()。 I only say may because, as Alex mentioned, there are some cases where onStop doesn't get called before the Activity is destroyed. 我只是说因为,正如亚力克提到的那样,在某些情况下,在销毁活动之前不会调用onStop。

onPause(): 在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." “如果一项活动失去焦点但仍然可见(即,一项新的非全尺寸或透明活动专注于您的活动之上),它会暂停。暂停的活动完全存在(它保持所有状态和成员信息并保持附加到窗口管理器),但可以在极低内存情况下被系统杀死。“

onStop(): 的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

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. 如果您正在模拟Android 4.x,您可以使用设置 - >开发者选项 - >不保持活动和后台进程限制来控制系统处理后台活动的方式。 For older versions there is an app called Dev Tools which contains the same settings. 对于旧版本,有一个名为Dev Tools的应用程序包含相同的设置。 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. 增加分配给模拟器的内存量可能会有所帮助。

Also, if you are re-launching your app from Eclipse, it will kill the previous process instead of gracefully terminating it. 此外,如果您从Eclipse重新启动应用程序,它将终止先前的进程,而不是正常终止它。

I agree with milter! 我赞同米勒!

onPause(): 在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." “如果一项活动失去焦点但仍然可见(即,一项新的非全尺寸或透明活动专注于您的活动之上),它会暂停。暂停的活动完全存在(它保持所有状态和成员信息并保持附加到窗口管理器),但可以在极低内存情况下被系统杀死。“

If you swap applications without pressing Back (press and hold HOME) then the OS is going to call onPause. 如果您在没有按Back(按住HOME)的情况下交换应用程序,则操作系统将调用onPause。 When you return to your activity (press and hold HOME again) in onResume you should have all of your private variables preserved. 当您返回到onResume中的活动(再次按住HOME)时,您应该保留所有私有变量。 But you can't control the user, right?! 但你无法控制用户,对吧?!

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. 我也有一个Timer,我需要保存经过的时间,所以当用户返回时我可以恢复数据。 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. 请记住,在我的情况下,字符串“elapsedTime”是系统的KEY,它必须是唯一的。 Use unique strings for each piece of data that you would like to save. 对要保存的每个数据使用唯一字符串。 For example "startClock", "ClockTextColor", etc... 例如“startClock”,“ClockTextColor”等......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM