Android 高工面試必考題(一):說說 Activity 的四種啓動模式,你還被問的瑟瑟發抖嗎?

今天分享一波面試系列,都是一些面試時肯定會被問到的問題,其中的內容也是和我被面試的實際情況息息相 關,希望能幫大家踩一點坑。

說說 Android 的四種啓動模式

這基本是一道必考題,和「 Activity 的生命週期 」一樣,基本爲必考題。

其實很多人可能存在一個誤區,覺得知道這個啓動模式「launchMode」沒什麼意義,但我在毫無準備的前提下,被問到這個問題的時候,我被問的瑟瑟發抖。

這些都是基本

先普及下可能大多數人都知道的基本見解。

  • standard

這是 Activity 的默認啓動模式,每次激活 Activity 的時候都會創建一個新的 Activity 實例,並放入任務棧中。使用場景:基本絕大多數地方都可以用。

  • singleTop

這可能也是非常常用的 launchMode 了。如果在任務的棧頂正好存有該 Activity 的實例,則會通過調用 onNewIntent() 方法進行重用,否則就會同 standard 模式一樣,創建新的實例並放入棧頂。即便棧中已經存在了該 Activity 的實例,也會創建新的實例,即:A -> B ->A,此時棧內爲 A -> B -> A,但 A -> B ->B ,此時棧內爲 A -> B。一句話概述就是:當且僅當啓動的 Activity 和上一個 Activity 一致的時候纔會通過調用 onNewIntent() 方法重用 Activity 。使用場景:資訊閱讀類 APP 的內容界面。

  • singleTask

這個 launchMode專門用於解決上面 singleTop 的另外一種情況,只要棧中已經存在了該 Activity 的實例,就會直接調用 onNewIntent() 方法來實現重用實例。重用時,直接讓該 Activity 的實例回到棧頂,並且移除之前它上面的所有 Activity 實例。如果棧中不存在這樣的實例,則和 standard 模式相同。即: A ->B -> C -> D -> B,此時棧內變成了 A -> B。而 A -> B -> C,棧內還是 A -> B -> C。使用場景:瀏覽器的主頁面,或者大部分 APP 的主頁面。

  • singleInstance

在一個新棧中創建該 Activity 的實例,並讓多個應用共享該棧中的該 Activity 實例。一旦該模式的 Activity 實例已經存在於某個棧中,任何應用再激活該 Activity 時都會重用該棧中的實例,是的,依然是調用 onNewIntent() 方法。其效果相當於多個應用共享一個應用,不管是誰激活,該 Activity 都會進入同一個應用中。但值得引起注意的是:singleInstance 不要用於中間頁面,如果用戶中間頁面,跳轉會出現很難受的問題。 這個在實際開發中我暫未遇到過,不過 Android 系統的來電頁面,多次來電均是使用的同一個 Activity 。

四種模式的背書式理解記憶講完了,你認爲這樣就結束了嗎?

對,我也一度是這樣認爲的。

再說說我們的 Intent 標籤

我們除了需要知道在 AndroidManifest.xml 裏面設置 android:launchMode 屬性,我們還需要了解下面這幾個 Intent 標籤的用法。

我們當然可以選擇看看官方文檔 Tasks and Back Stack (你可能需要梯子)。

在 Android 中,我們除了在清單文件 AndroidManifest.xml 中配置 launchMode,當然可以用 Intent 標籤說事兒。啓動 Activity ,我們需要傳遞一個 Intent,完全可以通過設置 Intent.setFlags(int flags) 來設置啓動的 Activity 的啓動模式。

需要注意的是:通過代碼來設置 Activity 的啓動模式的方式,優先級比清單文件設置更高。

  • FLAG_ACTIVITY_NEW_TASK

這個標識會使新啓動的 Activity 獨立創建一個 Task。

  • FLAG_ACTIVITY_CLEAR_TOP

這個標識會使新啓動的 Activity 檢查是否存在於 Task 中,如果存在則清除其之上的 Activity,使它獲得焦點,並不重新實例化一個 Activity,一般結合 FLAG_ACTIVITY_NEW_TASK 一起使用。

  • FLAG_ACTIVITY_SINGLE_TOP

等同於在 launcherMode 屬性設置爲 singleTop。

前面講了這麼多,似乎相當全面了,但你以爲這樣就結束了?No,面試官一般情況下已經不會這麼問你了,這樣問你完全可以背出來。

面試官怎麼問 Activity 的啓動模式(launchMode)?

怎麼問?

1、設置爲 singleTask 的啓動模式,當 Activity 的實例已經存在時,再啓動它,它的哪個回調函數會被執行?我們可以在哪個回調中處理新的 Intent 協帶的參數?(通過 startActivity(Intent) 方式啓動)

2、設置爲 singleTop 的啓動模式,當 Activity 的實例已經存在於 Task 的棧頂,我們可以在哪個回調中處理新的 Intent 協帶的參數?(在當前 Activity 中從通知欄點擊再跳轉到此 Activity 就是這種在棧頂的情況)

這兩個問題如果你看了上面的,一定對你來說實在太簡單了。面試官只是想直接考察你是否真正做過這樣的設置,或者是否知道 onNewIntent() 這個方法的存在。

有沒有其他想說的?

有。

之前在一篇文章中看到過這樣一種情況,發現之前同事寫的代碼導致了這樣一個問題。

startActivityForResult 啓動一個 Activity,還沒有開始界面跳轉,直接就執行了 onActivityResult()。

不知道有沒有人也遇到過這樣的問題,但我想遇到這個問題的時候,你一樣會因此而抓耳撓腮。(可能是因爲我們一般在排查問題的時候,很少去關注配置清單文件 AndroidManifests.xml。)

我們在 Activity.java 的 startActivityForResult() 方法中可以看到這樣一串說明。

很多人出現這個問題,確實是因爲 startActivityForResult() 啓動的 Activity 設置了 singleTask 的啓動模式。

好在 Android 5.0 以後,修正了這個問題。不過當你在 Intent 中設置 FLAG_ACTIVITY_NEW_TASK 後還是會出現這樣的問題。

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

注意:MainActivity 的 onResume() 也會被觸發。因爲 onActivityResult() 被執行時,它會重新獲得焦點。很多人也會遇到 onResume() 被無故調用,也許就是這種情況。

所以,最終我們發現只要是不和原來的 Activity 在同一個 Task 就會產生這種立即執行 onActivityResult() 的情況,從原代碼也可以得到驗證,詳情查看 ActivityStackSupervisor.java

小結

關於 Activity 的啓動模式相關的問題,其實還會有很多種考察你掌握情況的問法,建議採用 STAR 法則 進行面試回答。其實只要你掌握了實質,後面的運用只看你個人的運用能力和創新了。

最後

不用多說,相信大家都有一個共識:無論什麼行業,最牛逼的人肯定是站在金字塔端的人。所以,想做一個牛逼的程序員,那麼就要讓自己站的更高,成爲技術大牛並不是一朝一夕的事情,需要時間的沉澱和技術的積累。

關於這一點,在我當時確立好Android方向時,就已經開始梳理自己的成長路線了,包括技術要怎麼系統地去學習,都列得非常詳細。

這裏最後分享耗時一年多整理的一系列Android學習資源:Android源碼解析、Android第三方庫源碼筆記、Android進階架構師七大專題學習、歷年BAT面試題解析包、Android大佬學習筆記等等,這些內容均免費分享給大家,需要完整版的朋友,點這裏可以看到全部內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章