四大組件——Activity生命週期

Activity生命週期分析

  • Activiy啓動:onCreate() => onStart() => onResume()
2019-09-17 18:51:21.639 26091-26091/? D/LifeActivity: --------onCreate: 
2019-09-17 18:51:21.714 26091-26091/? D/LifeActivity: --------onStart: 
2019-09-17 18:51:21.716 26091-26091/? D/LifeActivity: --------onResume:
複製代碼
  • Activity 進入後臺 ( 按下Home 或啓動新 Activity ): onPause() => onStop()
2019-09-17 19:36:10.457 29902-29902/com.fr.myapplication D/LifeActivity: --------onPause: 
2019-09-17 19:36:10.929 29902-29902/com.fr.myapplication D/LifeActivity: --------onStop:
複製代碼
  • Activity 返回前臺: onRestart() => onStart() => onResume()
2019-09-17 19:36:15.411 29902-29902/com.fr.myapplication D/LifeActivity: --------onRestart: 
2019-09-17 19:36:15.412 29902-29902/com.fr.myapplication D/LifeActivity: --------onStart: 
2019-09-17 19:36:15.413 29902-29902/com.fr.myapplication D/LifeActivity: --------onResume:
複製代碼
  • 鎖屏: onPause() => onStop()
2019-09-17 19:36:10.457 29902-29902/com.fr.myapplication D/LifeActivity: --------onPause: 
2019-09-17 19:36:10.929 29902-29902/com.fr.myapplication D/LifeActivity: --------onStop:
複製代碼
  • 解鎖: onRestart() => onStart() => onResume()
2019-09-17 19:40:09.387 29902-29902/com.fr.myapplication D/LifeActivity: --------onRestart: 
2019-09-17 19:40:09.389 29902-29902/com.fr.myapplication D/LifeActivity: --------onStart: 
2019-09-17 19:40:09.391 29902-29902/com.fr.myapplication D/LifeActivity: --------onResume:
複製代碼

Activity生命週期回調方法

  • onCreate() 首次建立 Activity 時調用。 您應該在此方法中執行全部正常的靜態設置 — 建立視圖、將數據綁定到列表等等。 系統向此方法傳遞一個 Bundle 對象,其中包含 Activity 的上一狀態,不過前提是捕獲了該狀態 始終後接 onStart()。
  • onRestart() 在 Activity 已中止並即將再次啓動前調用。 始終後接 onStart() 在 Activity 已中止並即將再次啓動前調用。 始終後接 onStart()
  • onStart() 在 Activity 即將對用戶可見以前調用。 若是 Activity 轉入前臺,則後接 onResume(),若是 Activity 轉入隱藏狀態,則後接 onStop()。
  • onResume() 在 Activity 即將開始與用戶進行交互以前調用。 此時,Activity 處於 Activity 堆棧的頂層,並具備用戶輸入焦點。 始終後接 onPause()。
  • onPause() 當系統即將開始繼續另外一個 Activity 時調用。 此方法一般用於確認對持久性數據的未保存更改、中止動畫以及其餘可能消耗 CPU 的內容,諸如此類。 它應該很是迅速地執行所需操做,由於它返回後,下一個 Activity 才能繼續執行。 若是 Activity 返回前臺,則後接 onResume(),若是 Activity 轉入對用戶不可見狀態,則後接 onStop()。
  • onStop() 在 Activity 對用戶再也不可見時調用。若是 Activity 被銷燬,或另外一個 Activity(一個現有 Activity 或新 Activity)繼續執行並將其覆蓋,就可能發生這種狀況。 若是 Activity 恢復與用戶的交互,則後接 onRestart(),若是 Activity 被銷燬,則後接 onDestroy()。
  • onDestroy() 在 Activity 被銷燬前調用。這是 Activity 將收到的最後調用。 當 Activity 結束(有人對 Activity 調用了 finish()),或系統爲節省空間而暫時銷燬該 Activity 實例時,可能會調用它。 您能夠經過 isFinishing() 方法區分這兩種情形。

Activity的4種狀態

Running / Paused / Stopped / Killedandroid

Running

Activity處於活動狀態,此時Activity處於棧頂,是可見狀態,可與用戶進行交互。bash

Paused

當Activity失去焦點時,或被一個新的非全屏的Activity,或被一個透明的Activity放置在棧頂時,Activity就轉化爲Paused狀態。此時Activity只是失去了與用戶交互的能力,其全部的狀態信息及其成員變量都還存在,只有在系統內存緊張的狀況下,纔有可能被系統回收掉。app

Stopped

當一個Activity被另外一個Activity徹底覆蓋時,被覆蓋的Activity就會進入Stopped狀態,此時它再也不可見,可是跟Paused狀態同樣保持着其全部狀態信息及其成員變量。ide

Killed

當Activity被系統回收掉時,Activity就處於Killed狀態。佈局

Activity生命週期流程圖

activity_lifecycle.png

異常狀況下的生命週期分析

咱們知道,Activity除了受用戶操做所致使的正常的生命週期方法的調度,還有一些異常狀況,好比當資源相關的系統配置發生改變以及系統內存不足時,Activity就可能被殺死。學習

1. 資源相關的系統配置發生改變致使Activity被殺死並從新建立

例如當前的Activity處於豎屏狀態,若是忽然旋轉屏幕,因爲系統配置發生了改變,在默認的狀況下,Activity就會被銷燬而且從新建立,固然咱們能夠阻止系統從新建立咱們的Activity。 測試

異常狀況下Activity的重建過程.png

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
        outState.putString(TEXT,text);
    Log.d(TAG, "--------onSaveInstanceState: ");
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    text = savedInstanceState.getString(TEXT);
    Log.d(TAG, "--------onRestoreInstanceState: ");
}
複製代碼

注意:系統只有在Activity異常終止的時候纔會調用onSaveInstanceState和onRestoreInstanceState來儲存和恢復數據,其餘狀況下不觸發這個過程動畫

2.資源內存不足致使低優先級的Activity被殺死

Activity按照優先級從高到低,能夠分爲如下三種ui

  • (1) 前臺Activity——正在和用戶交互的Activity,優先級最高。
  • (2) 可見但非前臺的Activity——好比Activity中彈出一個對話框,致使Activity可見但位於後臺沒法和用戶直接交互。
  • (3) 後臺Activity——已經被暫停的Activity,好比執行onStop,優先級最低。

當系統的內存不足時,系統會按照上述的優先級去殺死目標Activity所在的進程,並在後續經過onSaveInstanceState和onRestoreInstanceState來儲存和恢復數據。this

configChanges

在AndroidManifest.xml中設置configChanges屬性的值可使系統配置發生變化後,Activity不被從新建立,以達到和onSaveInstanceState和onRestoreInstanceState來儲存和恢復數據同樣的效果。

<activity android:name=".LifeActivity"
    android:configChanges="orientation|screenSize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
 </activity>
複製代碼
附上代碼:
Activity部分
public class LifeActivity extends AppCompatActivity {
    private static final String TAG = "LifeActivity";
    private static final String TEXT = "text";
    private EditText editText;
    private String text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "--------onCreate: ");
        setContentView(R.layout.activity_life);

        editText = findViewById(R.id.et_text);
        text = String.valueOf(editText.getText());
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "--------onStart: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "--------onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "--------onStop: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "--------onResume: ");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "--------onRestart: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "--------onDestroy: ");
    }

    public void click(View view) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(TEXT,text);
        Log.d(TAG, "--------onSaveInstanceState: ");
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        text = savedInstanceState.getString(TEXT);
        Log.d(TAG, "--------onRestoreInstanceState: ");
    }
}
複製代碼

其中的MainActivity,爲頁面內跳轉測試當前生命週期而存在,可爲任意一個Activity此處就不貼出代碼了

佈局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity學習.LifeActivity">

    <Button
        android:id="@+id/bt_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="點擊跳轉"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        tools:ignore="HardcodedText"
        android:onClick="click"/>

    <EditText
        android:id="@+id/et_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:hint="輸入內容"
        app:layout_constraintTop_toBottomOf="@id/bt_click"
        android:inputType="text"
        android:imeOptions="actionDone"/>

</androidx.constraintlayout.widget.ConstraintLayout>
複製代碼
相關文章
相關標籤/搜索