四大組件——Activity(1)

一.Activity的生命週期

按照慣例,先放一張Activity生命週期的圖片,能夠先從總體把握生命週期中各個方法的調用順序,稍後再從代碼中對各個方法調用作相關說明。

從圖中咱們能夠看出,Activity的主要生命週期有:onCreate()OnStart()OnRestart()OnResume()OnPause()OnStop()OnDestroy() 這7個方法。java

二. 項目工程說明

採用語音:Kotlin(基於1.2.61)
測試機:魅族 M15(基於Android 7.1.2)
項目名稱:activity_basic_use
編譯版本:
minSdkVersion 17
targetSdkVersion 26
複製代碼

三.生命週期方法的調用

先新建4個文件,MainActivitySecondActivityThirdActivityFourthActivity,其中MainActivity用來作跳轉測試的主ActivitySecondActivity是普通的ActivityThirdActivity是以Dialog形式顯示的ActivityFourthActivity使用透明主題的普通Activity,並新建4個佈局文件,佈局文件很簡單,再也不貼出佈局文件中的代碼,而後覆寫相關的生命週期的方法,下面是MainActivity代碼:git

class MainActivity : Activity() {

    private var button1:Button? = null
    private var button2:Button? = null
    private var button3:Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button1 = findViewById(R.id.button1)
        button2 = findViewById(R.id.button2)
        button3 = findViewById(R.id.button3)
        button1?.setOnClickListener {
            val intent = Intent(this,SecondActivity::class.java)
            startActivity(intent)
        }
        button2?.setOnClickListener {
            val intent = Intent(this,ThirdActivity::class.java)
            startActivity(intent)
        }
        button3?.setOnClickListener {
            val intent = Intent(this,FourthActivity::class.java)
            startActivity(intent)
        }
        println("MainActivity->onCreate")
    }

    override fun onStart() {
        super.onStart()
        println("MainActivity->onStart")
    }

    override fun onRestart() {
        super.onRestart()
        println("MainActivity->onRestart")
    }

    override fun onResume() {
        super.onResume()
        println("MainActivity->onResume")
    }

    override fun onPause() {
        super.onPause()
        println("MainActivity->onPause")
    }

    override fun onStop() {
        super.onStop()
        println("MainActivity->onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        println("MainActivity->onDestroy")
    }
}
複製代碼

而後是SecondActivity裏面的代碼:github

class SecondActivity : Activity() {

    private var button2: Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        button2 = findViewById(R.id.button2)
        button2?.setOnClickListener{
            finish()
        }
        println("SecondActivity->onCreate")
    }

    override fun onStart() {
        super.onStart()
        println("SecondActivity->onStart")
    }

    override fun onRestart() {
        super.onRestart()
        println("SecondActivity->onRestart")
    }

    override fun onResume() {
        super.onResume()
        println("SecondActivity->onResume")
    }

    override fun onPause() {
        super.onPause()
        println("SecondActivity->onPause")
    }

    override fun onStop() {
        super.onStop()
        println("SecondActivity->onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        println("SecondActivity->onDestroy")
    }
}
複製代碼
  1. 首次運行程序,獲得如下輸出:
  2. 按下Home鍵後,再次點擊應用圖標後,獲得如下輸出:
  3. 按下返回鍵後,獲得如下輸出:
  4. 從新運行程序,點擊button1按鈕後,跳轉到SecondActivity,獲得如下輸出:
  5. 點擊SecondActivity中的按鈕後,獲得如下輸出:
  6. 從新運行程序,點擊button2按鈕後,彈出Dialog形式的ThirdActivity,獲得如下輸出:
  7. 點擊ThirdActivity中的按鈕後,獲得如下輸出:
  8. 從新運行程序,點擊button3按鈕後,顯示透明主題的Activity,獲得如下輸出:
  9. 點擊FourthActivity中的按鈕後,獲得如下輸出:

四.生命週期方法說明(《Android開發藝術探索》)

onCreate()面試

這是生命週期的第一個方法,表示Activity正在建立,在這個方法中,咱們能夠作一些初始化操做,好比加載佈局資源、初始化Activity相關數據等。bash

onStart()ide

表示Activity正在被啓動即將開始,這時Activity已經可見了,只不過尚未出如今前臺,沒法和用戶進行交互。能夠理解爲Activity已經顯示出來了,可是用戶看不到。佈局

onRestart()測試

表示Activity正在從新啓動,通常狀況下,當Activity從不可見狀態從新變爲可見狀態後,此方法就會被回調,這種情形通常都是用戶行爲所致使的,好比用戶按下Home鍵後或者打開了一個新的Activity,接着又回到了這個Activity,就會出現這種狀況。字體

onResume()動畫

表示Activity已經可見了,而且出如今前臺開始活動,能夠和用戶進行交互。須要注意onStartonResume的對比,兩者都表示Activity可見,可是onStart表示Activity在後臺而且沒法和用戶進行交互,而onResume表示Activity已經顯示在前臺,能夠和用戶進行交互。

onPause()

表示Activity正在被中止,此時能夠作一些數據存儲、動畫中止等,但不能是耗時的操做。通常狀況下會接着回調onStop方法,若是此時再次回到這個Activity後,會接着回調onResume方法。但也有特殊狀況,好比顯示一個以Activity形式的Dialog或者採用了透明主題就不會回調onStop方法。

onStop()

表示Activity正在被中止,此時Activity變得不可見,在這個方法中能夠作一些稍微重量級的回收工做,但也不能太耗時。

onDestroy()

表示Activity正在被銷燬,這是Activity生命週期的最後一個方法,在這個方法中,咱們能夠作回收工做和一些資源的釋放。

總結

從整個生命週期來講,onCreate()onDestroy()是配對的,表示Activity的建立和銷燬,而且只能回調一次;onStart()onStop()是配對的,這是從Activity是否可見來講的,隨着用戶的操做和屏幕的點亮或者熄滅,這2個方法會回調屢次;onResume()onPause()是配對的,這是從Activity是否在前臺來講的,隨着用戶的操做和屏幕的點亮或者熄滅,這2個方法會回調屢次。onStart()+onStop()onResume()+onPause(),這兩組回調方法表示的意義不一樣,onStart()+onStop()是從Activity是否可見這個角度來回調的,onResume()+onPause()是從Activity是否位於前臺這個角度來回調的,除了這種區別,在實際使用中並無其餘明顯區別。

五.其餘狀況生命週期回調

鎖屏

鎖屏後,若是當前 Activity沒有被系統回收,就是普通的切換到不可見狀態;若是被系統回收後,會銷燬當前 Activity,而後從新建立一個。

旋轉屏幕(程序運行時,默認都是豎屏)

  1. 未在Manifest中進行設置,豎屏切到橫屏(橫屏再切回到豎屏,輸出是和下面同樣的,也就是說會回調2次):
    能夠看出旋轉屏幕後,Activity被銷燬,而後從新建立,此時就算重寫了onConfigurationChanged方法,也不會調用此方法
  2. Manifest中設置MainActivityconfigChanges="orientation|screenSize",並重寫onConfigurationChanged方法,會獲得如下輸出:
  • 豎屏切到橫屏:
    能夠看到,Activity並無銷燬,而是回調了onConfigurationChanged方法
  • 橫屏切回到豎屏:
    能夠看到,Activity也沒有被銷燬,也是回調了onConfigurationChanged方法

故從以上能夠知道,配置configChanges="orientation|screenSize"能夠阻止Activity的銷燬與從新建立,若是少了其中的任何一個,都會致使Activity的銷燬。

  • configChanges經常使用屬性值的相關說明:
屬性值 說明
locale 用戶所在區域發生變化,通常是用戶切換了語言
keyboardHidden 鍵盤的可用性發生了改變,好比調出或隱藏了鍵盤
fontScale 字體比例發生了變化
orientation 屏幕方向發生了變化
screenSize 屏幕尺寸發生了變化

更多的屬性值,直接截取《Android開發藝術探索》中的圖:

保存數據

屏幕方向發生了旋轉,或者Activity因爲資源內存不足被系統殺死等異常銷燬,而且有機會從新顯示,系統會回調兩個方法:onSaveInstanceState(outState:Bundle?)onRestoreInstanceState(savedInstanceState:Bundle?)。若是在EditText或者其餘控件中有值的話,能夠在onSaveInstanceState方法中,調用Bundle對象的相關putXxx方法進行存儲,而後在onRestoreInstanceState方法或者onCreate中調用BundlegetXxx方法進行獲取對應的值,通常咱們推薦在onCreate中進行獲取。注意:在正常的生命週期中並不會回調這兩個方法

項目地址: github.com/leewell5717…

六. 總結

本文對Activity生命週期的基礎作了一些講述,生命週期對於咱們來講是很是重要的,也有許多面試官喜歡問關於生命週期的基礎,可能本文總結的不是很全面,或者有錯誤的地方,歡迎指出,也歡迎給我一些建議,我將在後面的寫做中提高本身。

相關文章
相關標籤/搜索