Activity生命周期之停止和重启(Stopping and Restarting)一个Activity

2018年01月20日 08:53 | 2932次浏览

正确地停止和重启你的activity在activity的生命周期中是一个很重要的过程,这样能够确保你的用户感觉到你的应用一直都活着并且没有丢失进度。你的activity的停止和重启时有几个重要的场景:

用户打开最近运行应用的窗口并且切换到其他的应用中,你当时在前台的activity被停止了。如果用户从主界面回到你的应用,这个activity将重启。

用户在你的应用中执行一个操作跳转到其他的应用中。当第二个activity启动时,当前的activity被停止。如果用户之后点击返回键,第一个activity就会重启。

当用户在使用你的应用时接到一个电话。

Activity 类提供了这两个生命周期方法,onStop() 和onRestart(),来允许你指定如何处理activity被停止和重启的情况。不像暂停状态,有一部分UI被遮挡,停止状态下UI完全不可见,同时用户的焦点在另一个activity上(或者另一个应用)。


提示: 由于当应用被停止时系统用仍然将你的Activity 的实例保存在系统内存中,你完全没有必要实现onStop()onRestart()(或者甚至onStart() )方法。对于大多数相对简单的activity来说,activity会很正常的停止和重启,你可能只需要使用onPause() 方法来暂停正在进行的操作以及切断对系统资源的使用。

图 1. 当用户离开你的activity,系统调用onStop() 方法来停止你的

(1)。如果用户回到被停止的activity中,系统会调用onRestart() 方法

(2),很快会接着调用onStart() 

(3)和onResume() 方法

(4)。注意不管是哪个场景导致activity停止,系统总是会在调用onStop()方法之前先调用onPause()方法。


停止一个Activity

当你的activity接收到onStop() 方法的回调,由于用户不再使用它,这个activity不再可见并且需要释放几乎所有它不再需要的资源。一旦你的activity被停止,系统可能会销毁它的实例如果系统需要回收内存。在极端情况下,系统可能会简单的杀死你的应用的进程而不调用activity最后的onDestroy() 回调,所以使用onStop() 回调释放资源相当重要,否则会造成内存溢出。


即使onPause() 方法在onStop()方法之前被调用,你应该使用onStop() 方法来执行更大的,CPU密集型的关闭操作,例如向数据库写数据。


举例说明,下面是一个onStop() 方法的实现,它将草稿内容保存到持久化存储中:

@Override
protected void onStop() {
    super.onStop();  // Always call the superclass method first

    // Save the note's current draft, because the activity is stopping
    // and we want to 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,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
            );
}

当你的activity停止,Activity 对象保持常驻内存,在activity恢复后会再次被使用到。你不必重新初始化在任何回调方法中创建的组件来到达Resumed状态。系统也不会保存布局中每个视图的栈,因此如果用户向EditText 部件中写入了数据,那么这些内容会被保存起来,你没有必要保存以及重新载入它们。


提示: 甚至是当系统销毁了你的activity在它停止的时候,系统仍然记录着视图对象的状态(例如EditText中的文本)到一个 Bundle 中(一个key-value 对块)并且在用户回到相同的activity实例时重新载入它们(下堂课会介绍更多如何使用Bundle 来保存数据状态,在你的activity被销毁核重新创建的时候)。


开启/重启你的Activity

当你的activity从停止状态重新回到前端时,它会收到onRestart()回调。系统同时还会调用onStart() 方法,activity每次变可见的时候都会调用这个方法(不管是被重启还是第一次被创建时)。然而onRestart() 方法只会在用户从停止状态恢复时才会被调用,因此你可以使用它来执行一些之前activity被停止前没有被销毁。


一个应用需要使用onRestart() 方法来重新载入activity的状态的做法是不常见的,因此没有任何对这个方法的指引,被应用到通用人群的应用中。然而,由于你需要在onStop() 方法中清理你的activity的资源你需要在activity重启时重新初始化他们。你同样需要在你的activity第一次被创建时初始化它们(当已经没有这个activity的实例时)。鉴于这个原因,在从停止状态创建或者重启你的activity时,你应该使用onStart() 方法来对应onStop() 方法。

例如,用户可能在他再次回到你的应用之间过了很久,onStart() 方法是一个很好的验证系统特性是否被开启的地方:

@Override
protected void onStart() {
    super.onStart();  // Always call the superclass method first
    
    // The activity is either being restarted or started for the first time
    // so this is where 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 an intent
        // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
        // 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
    
    // Activity being restarted from stopped state    
}

当系统销毁你的activity,它会调用onDestroy() 方法。由于你通常应该在onStop()方法中释放了大部分的资源,当系统调用onDestroy()时就没有太多的东西需要做。这个方法是清理可能导致内存泄漏的最后的方法,因此你需要确保那些附加线程以及其他的长时间操作(像方法跟踪)都被停止。



小说《我是全球混乱的源头》

感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程