2.3停止和重新启动活动
正确地停止与重新启动您的活动,在活动生命周期中是一个重要的过程,它确保您的用户感知到你的应用永远是活动的,并没有丢失他们的进度。有几个关键场景,您的活动将会停止并重新启动:
· 用户打开最近应用程序窗口,并从你的应用程序切换到另一个应用程序。你的应用程序中目前在前台的活动就停止。如果用户通过主屏幕启动图标或最近使用的应用程序窗口返回到您的应用程序,活动将重新启动。
· 用户在你的应用程序执行一个动作,开启一个新的活动。在第二个活动创建时,当前的活动就停止。如果用户接着按下“ 返回“按钮时,第一个活动会重新启动。
· 用户在他或她的手机上使用您的应用程序时接到一个电话。
活动类提供了两个生命周期方法onStop()和onRestart() ,让你在活动停止和重新启动时专门处理它。与标识部分UI被遮挡的暂停状态不同的是,停止状态表明用户界面是不再可见,用户的焦点是在另一个活动(或另一个的应用程序)。
注:由于在你的活动实例停止时,系统保留它在系统内存中,你可能并不需要实现 onStop()和onRestart()方法(或onStart()方法都不用)。对于大多数比较简单的活动,活动可以很好地停止和重新启动,你可能只需要使用onPause()方法暂停正在进行的行动,并断开系统资源。
图1:当用户离开你的活动时,系统调用onStop()停止活动(1)。如果用户在活动停止时返回,系统调用onRestart()(2),紧接着调用onStart()(3)和onResume()(4) 。请注意,无论在什么样的情况下导致活动停止,系统总是调用onStop()前调用onPause() 。
停止你的活动
当您的活动收到onStop()方法的调用时,它不再可见,用户不使用它时应该释放几乎所有不需要的资源。一旦您的活动停止了,如果需要回收系统内存,系统可能会销毁这个活动实例。在极端的情况下,系统可能只是杀掉了你的应用程序的过程而并不调用活动最终的OnDestroy()回调方法,所以使用onStop()来释放可能会导致内存泄漏的资源对你很重要。
虽然onPause()方法在onStop()之前调用 ,你应该使用onStop()执行大量的更密集的CPU关闭操作,比如将信息写入到数据库。
例如,这里有一个onStop()方法的实现,它把草稿的内容保存到永久存储中:
@Override
protected void onStop() {
super.onStop(); // Always call the superclass method first
// Save thenote's current draft, because the activity is stopping
// and we wantto be sure the current note progress isn't lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
getContentResolver().update(
mUri, // TheURI for the note to update.
values, // The map ofcolumn names and new values to apply to them.
null, // NoSELECT criteria are used.
null // No WHERE columns are used.
);
}
当你的活动停止后,活动对象是驻留在内存中,在活动恢复时被召回。在恢复状态你不需要重新初始化任何回调方法中创建的组件。该系统还为布局中的每个视图跟踪当前状态,所以如果用户输入文本到一个EditText部件,该内容将被保留,所以你就不需要保存和恢复它。
注:即使系统在你的活动停止时销毁了它,系统仍然在一个Bundle(键-值对集合)中保留视图对象的状态(比如一个EditText中的文本),并在用户导航回到同一个活动实例时恢复它们(下一课中会更多地谈论关于使用Bundle保存其它状态数据,以防你的活动被销毁并重新创建)。
启动/重新启动你的活动
当你的活动从停止状态回到前台,它会接收到 onRestart()方法的调用。每次当您的活动变得可见时,系统还会调用OnStart()方法(无论是重新启动还是第一次创建)。然而,onRestart()方法只有在活动从停止状态恢复时被调用,所以你可以用它来执行一些特殊的恢复工作,那些可能只有当活动之前是停止而不是被销毁时才必需的恢复。
一个应用程序要使用onRestart()在还原活动的状态是很少见的,所以这个方法没有适用于普遍应用的指南。然而,因为您的onStop() 方法基本上会清理所有的活动的资源,你需要在活动重新启动时重新实例化它们。但是,当你第一次创建活动时(没有现成的活动实例的时候),你也需要实例化它们。基于这个原因,你通常会配对地使用OnStart()回调方法和onStop()方法,因为活动创建时和活动从停止状态重新启动时,系统都会调用OnStart()方法。
例如,由于用户可能在回到您的应用程序之前已经远离它很长一段时间了,OnStart()方法是一个很好的验证所需的系统功能已经启用的地方:
@Override
protected void onStart() {
super.onStart(); // Always call the superclass method first
// Theactivity is either being restarted or started for the first time
// so this iswhere we should make sure that GPS is enabled
LocationManager locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsEnabled) {
// Create a dialog here that requests the user to enable GPS, and use anintent
// with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGSaction
// to take the user to the Settings screen to enable GPS when they click"OK"
}
}
@Override
protected void onRestart() {
super.onRestart(); // Always call the superclass method first
// Activitybeing restarted from stopped state
}
当系统销毁您的活动时,它对您的活动调用OnDestroy() 方法。因为你通常应该已经在onStop()方法中释放了你的大部分资源,当接收到OnDestroy()调用的时候,大多数应用程序没有太多的东西需要做了。这个方法是你清理可能会导致内存泄漏的资源的最后机会,所以你应该确保额外的线程被销毁,其他长期运行的操作(如方法跟踪)要停止。