22

我是 Android 开发的新手,我仍然无法理解活动中的onPause()onStop()方法。

在我的应用程序中,我有一个名为 Counter 的静态类,它将变量的状态保存在应用程序的内存中。我的应用程序在模拟器中运行良好。我试图测试的是onPause()vs的不同行为onStop()

对于onPause,我希望保留存储在 Counter 类成员中的值,而调用onStop()我希望将计数器值重置为零。所以我覆盖onStop()并将计数器类中的变量设置为零。但是,在模拟器中,我似乎无法让应用程序处于暂停状态。在模拟器中,我打开我的应用程序,练习它。然后我点击模拟器的主页按钮(不是后退按钮),并启动另一个应用程序,相信这会模仿onPause()活动。但是,模拟器似乎不支持这一点(我使用的是 armeabi v7a 模拟器),它似乎总是在调用onStop(),因为我的计数器值都回到零,根据我在onStop(). 这是模拟器固有的还是我做错了什么让我的活动进入暂停状态?

4

6 回答 6

26

我不确定您正在使用哪个模拟器进行测试,但onPause它是始终保证在您Activity失去焦点时调用的一种方法(我说总是因为在某些设备上,特别是那些运行 Android 3.2+ 的设备,onStop并不总是保证在被销毁之前被调用Activity)。

了解初学者生命周期的一个好方法Activity是用Logs 乱扔你的重写方法。例如:

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 -");
    }
}
于 2012-07-08T22:57:30.243 回答
13

我知道您的问题是 6 个月前的问题,但万一其他人偶然发现了这个问题:

我做错了什么让我的活动进入暂停状态。

是的,你是。这个:

我点击了模拟器的主页按钮(不是返回按钮),然后启动另一个应用程序,相信这会模仿 onPause() 活动。

点击主页按钮确实会调用该onPause()方法,但由于主页按钮使您的活动不再可见,因此它将调用该onStop()方法(如提到的爱国者和米尔特)。

根据活动开发人员参考 ( http://developer.android.com/guide/components/activities.html ),您可以显示一个对话框或简单地让设备进入睡眠状态。

或者,您调用一个只会部分阻碍调用活动的活动。因此,调用一个创建具有大小视图的窗口的活动:

 android:layout_width="100dp"
 android:layout_height="100dp"

它不会覆盖整个屏幕,从而使调用活动部分可见,从而仅调用调用活动的onPause()方法。

克隆该活动,以便两个视图大小都是“match_parent”而不是“100dp”并调用它,调用活动的onPause()onStop()方法都将被调用,因为调用活动将不可见。

当然也有例外,比如被调用的 Activity 导致应用程序崩溃onCreate()onStart()或者调用 ActivityonResume()onStop()不会被调用,显然,我在这里只讨论一般情况。

于 2013-04-03T13:49:59.173 回答
4

何时调用 onPause() 和 onStop() 之间的差异可能非常微妙。然而,正如这里所解释的,onPause() 通常会在当前 Activity 仍在运行时在另一个Activity获得焦点(可能是弹出窗口或透明窗口)时执行。如果您完全离开应用程序(例如,通过点击主页按钮),活动将不再可见,系统可能会执行 onStop()。我只说可能是因为,正如 Alex 所提到的,在某些情况下 onStop 在 Activity 被销毁之前没有被调用。

于 2012-07-08T22:46:38.680 回答
2

暂停():

“如果一个活动失去了焦点但仍然可见(即一个新的非全尺寸或透明活动的焦点在你的活动之上),它就会被暂停。一个暂停的活动是完全活跃的(它保持所有状态和成员信息并保持连接到窗口管理器),但可以在内存极低的情况下被系统杀死。”

停止():

“如果一个活动被另一个活动完全遮挡,它就会停止。它仍然保留所有状态和成员信息,但是,它不再对用户可见,因此它的窗口是隐藏的,并且经常会在内存时被系统杀死其他地方需要。”

取自android参考活动类:http: //developer.android.com/reference/android/app/Activity.html

于 2012-07-08T22:59:38.073 回答
1

我同意米尔特!

暂停():

“如果一个活动失去焦点但仍然可见(也就是说,一个新的非全尺寸或透明活动的焦点在你的活动之上),它就会被暂停。一个暂停的活动是完全活跃的(它保持所有状态和成员信息并保持连接到窗口管理器),但可以在内存极低的情况下被系统杀死。”

如果您在不按返回(按住 HOME)的情况下交换应用程序,那么操作系统将调用 onPause。当您在 onResume 中返回活动(再次按住 HOME)时,您应该保留所有私有变量。但是你不能控制用户,对吧?!

如果您预计用户将离开您的应用并且操作系统调用您的 onStop,如果您打算从中断的地方继续,则最好保存您的数据。

我也有一个计时器,我需要保存经过的时间,这样当用户返回时,我可以恢复数据。这是我要保存的示例:

@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. 
} 

还有我要恢复的代码:

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

将这些方法放在你的类中,你就可以开始了。请记住,在我的例子中,字符串“elapsedTime”是系统的关键,它必须是唯一的。为您要保存的每条数据使用唯一的字符串。例如“startClock”、“ClockTextColor”等...

于 2013-06-09T17:00:40.387 回答
1

如果您正在模拟 Android 4.x,您可以使用设置 -> 开发人员选项 -> 不保留活动和后台进程限制来控制系统处理后台活动的方式。对于旧版本,有一个名为 Dev Tools 的应用程序,其中包含相同的设置。但是,在内存不足的情况下,系统可以忽略这些设置并终止您的应用程序。增加分配给模拟器的内存量可能会有所帮助。

此外,如果您从 Eclipse 重新启动您的应用程序,它将终止前一个进程,而不是优雅地终止它。

于 2012-07-08T23:06:58.683 回答