金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

南方吳彥祖_藍斯發表於2020-09-20

又要到金九銀十的跳槽季了,為了讓更多的小夥伴可以在面試的時候取的更好的offer,不定期都會分享BAT常問面試題,由於內容較多,預計閱讀需要....3個月

所以就直接給你們安排好pdf吧~

點選這裡可直接下載

今天主要來講一下四大元件中的Activity相關的知識點:

描述一下Activity 生命週期?

  • onCreate() Activity第-次被建立的時候呼叫,一些初始化操作可以在這裡完成。
  • onStart() 這個方法在Activity 由不可見變為可見的時候呼叫。
  • onResume() 這個方法在Activity 準備好和使用者進行互動的時候呼叫。此時的Acivity一定位於返回棧的棧頂,並且處於執行狀態。
  • onPause() 這個方法在系統準備去啟動或者恢復另-個Activity的時候呼叫。
  • onStop() 這個方法在Activity 完全不可見的時候呼叫。它和onPause()方法的主要區別在於,如果啟動的新Activity 是一個對話方塊式的Activity,那麼onPause()方法會得到執行,而onStop()方法並不會執行。
  • onDestroy() 這個方法在Activity被銷燬之前呼叫,之後Activity的狀態將變為銷燬狀態。
  • onRestart 這個方法在Activity由停止狀態變為執行狀態之前呼叫,也就是Activity被重新啟動了。

生命週期:為了鞏固記憶,畫了一遍。

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

Activity之間跳轉時的生命週期

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

A Activity 開啟 B Activity 時都有哪些生命週期回撥?

A.onPause -> B.onCrete -> B.onStart -> B.onResume -> A.onStop

這樣回答只是及格,因為僅在 B Activity 的 launchMode 為 standard 或者 B Activity 沒有可複用的例項時是這樣的。

當 B Activity 的 launchMode 為 singleTop 且 B Activity 已經在棧頂時(一些特殊情況如通知欄點選、連點),此時只有 B 頁面自己有生命週期變化:

B.onPause -> B.onNewIntent -> B.onResume

當 B Activity 的 launchMode 為 singleInstance ,singleTask 且對應的 B Activity 有可複用的例項時,生命週期回撥是這樣的:

A.onPause -> B.onNewIntent -> B.onRestart -> B.onStart -> B.onResume -> A.onStop -> ( 如果 A 被移出棧的話還有一個 A.onDestory)

Activity的啟動模式

有4種啟動模式:

  • standard 標準模式
  • singleTop 棧頂複用模式
  • singleTask 棧內複用模式
  • singleInstance 單例模式

標準模式:每次啟動時,都會建立一個新的例項在棧頂
棧頂複用模式:如果需要新建立的例項就在棧頂,那麼就不會去重建,而是重用,否則就重新建立。
棧內複用模式:如果例項在當前棧中已經存在,就會將當前例項上面的其他例項都移除棧。
單例模式:直接建立一個新的棧並且建立例項放在棧中。

使用方式:
1.可以在在AndroidMainifest的Activity配置進行設定:android:launchMode="啟動模式"
2.透過 Intent設定標誌位

val intent=Intent(this,SocendActivity::class.java)intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)startActivity(intent)//其中標誌位屬性FLAGACTIVITYSINGLE_TOP:指定啟動模式為棧頂複用模式( SingleTop)
FLAGACTIVITYNEW_TASK: 指定啟動模式為棧內複用模式( SingleTask)
FLAGACTIVITYCLEAR_TOP:所有位於其上層的Activity都要移除, SingleTask模式預設具有此標記效果
FLAGACTIVITYEXCLUDEFROMRECENTS:具有該標記的Activity不會出現在歷史Activity的列表中,即無法透過歷史列表回到該Activity上

那麼這兩種方式有什麼區別呢?

  • 優先順序不同 Intent設定方式的優先順序 > Manifest設定方式,即 以前者為準
  • 限定範圍不同 Manifest設定方式無法設定 FLAG_ACTIVITY_CLEAR_TOP; Intent設定方式 無法設定單例模式( SingleInstance)

onStart,onStop和onResume,onPause的區別?

Activity的生命週期中,大部分都是兩兩相對的,可以將其分為3種,前臺,可見,後臺。 onStart,onStop之間所經歷的是可見的,但是卻可能無法與使用者互動。 onResume,onPause之間所經歷的是屬於前臺,這時候使用者是可以互動的。

如果新Activity是透明主題時,舊Activity會不會走onStop?

不會!

鎖定屏與解鎖螢幕,Activity如何執行生命週期的?

鎖屏時只會呼叫onPause(),而不會呼叫onStop方法,開屏後則呼叫onResume()。

橫豎屏切換時的生命週期?

如果清單檔案中沒有設定android:configChanges屬性時,生命週期:先銷燬onPause()、onStop()、onDestroy()再重新建立onCreate()、onStart()、onResume()方法。
設定orientation|screenSize(一定要同時出現)屬性值時,不走生命週期方法,只會執行onConfigurationChanged()方法。

彈出 Dialog 對生命週期有什麼影響?

我們知道,生命週期回撥都是 AMS 透過 Binder 通知應用程式呼叫的;而彈出 Dialog、Toast、PopupWindow 本質上都直接是透過 WindowManager.addView() 顯示的(沒有經過 AMS),所以不會對生命週期有任何影響。

如果是啟動一個 Theme 為 Dialog 的 Activity , 則生命週期為:

A.onPause -> B.onCrete -> B.onStart -> B.onResume

注意:這邊沒有前一個 Activity 不會回撥 onStop,因為只有在 Activity 切到後臺不可見才會回撥 onStop;而彈出 Dialog 主題的 Activity 時前一個頁面還是可見的,只是失去了焦點而已所以僅有 onPause 回撥。

Activity 在 onResume 之後才顯示的原因是什麼?

雖然我們設定 Activity 的佈局一般都是在 onCreate 方法裡呼叫 setContentView 。裡面是直接呼叫 window 的 setContentView,建立一個 DecorView 用來包住我們建立的佈局。詳情如下:

PhoneWindow.javapublic void setContentView(int layoutResID) {
    if (mContentParent == null) {
        installDecor();
    } 
    ...
    // 載入佈局,新增到 mContentParent
    // mContentParent 又是 DecorView 的一個子佈局  
    mLayoutInflater.inflate(layoutResID, mContentParent);}

然而這一步只是載入好了佈局,生成一個 ViewTree , 具體怎麼把 ViewTree 顯示出來,答案就在下面:

ActivityThread.java
public void handleResumeActivity(...){
    // onResume 回撥
    ActivityClientRecord r = performResumeActivity(...)
    final Activity a = r.activity;
    if (r.window == null && !a.mFinished && willBeVisible) {
        r.window = r.activity.getWindow();
        View decor = r.window.getDecorView();
        ViewManager wm = a.getWindowManager();
        wm.addView(decor, l);// 重點
    }}

WindowManager 的 addView 方法最終將 DecorView 新增到 WMS ,實現繪製到螢幕、接收觸屏事件。具體的呼叫鏈如下:

   WindowManagerImpl.addView-> WindowManagerGlobal.addView-> ViewRootImpl.setView     
-> ViewRootImpl.requestLayout() // 執行 View 的繪製流程
   // 透過 Binder 呼叫 WMS ,WMS 會新增一個 Window 相關的物件
   // 應用端透過 mWindowSession 呼叫 WMS
   // WMS 透過 mWindow (一個 Binder 物件) 呼叫應用端  
   mWindowSession.addToDisplay(mWindow)

綜上,在onResume回撥之後,會建立一個 ViewRootImpl ,有了它之後應用端就可以和 WMS 進行雙向呼叫了。

onActivityResult 在哪兩個生命週期之間回撥?

onActivityResult 不屬於 Activity 的生命週期,一般被問到這個問題時大家都會懵逼。

其實答案很簡單,onActivityResult 方法的註釋中就寫著答案:

「You will receive this call immediately before onResume() when your activity is re-starting.」

跟一下程式碼(TransactionExecutor.execute 有興趣的可以自己打斷點跟一下),會發現 onActivityResult 回撥先於該 Activity 的所有生命週期回撥,從 B Activity 返回 A Activity 的生命週期呼叫為:

B.onPause -> A.onActivityResult -> A.onRestart -> A.onStart -> A.onResume

onCreate 方法裡寫死迴圈會 ANR 嗎?

ANR 的四種場景:

  • Service TimeOut: service 未在規定時間執行完成:前臺服務 20s,後臺 200s
  • BroadCastQueue TimeOut: 未在規定時間內未處理完廣播:前臺廣播 10s 內, 後臺 60s 內
  • ContentProvider TimeOut: publish 在 10s 內沒有完成
  • Input Dispatching timeout: 5s 內未響應鍵盤輸入、觸控螢幕等事件

我們可以看到,Activity 的生命週期回撥的阻塞並不在觸發 ANR 的場景裡面,所以並不會直接觸發 ANR。
只不過死迴圈阻塞了主執行緒,如果系統再有上述的四種事件發生,就無法在相應的時間內處理從而觸發 ANR。

onNewIntent是什麼時候呼叫的?

如果需要啟動的例項是之前有開啟過的,並且在棧的頂部,目前處於onPause、onStop 的狀態,其他例項再次進入的話,執行順序為:onNewIntent,onRestart,onStart,onResume。

onSaveInstanceState()方法的作用?

異常情況下 系統配置發生改變時導致Activity被殺死並重新建立、資源記憶體不足導致低優先順序的Activity被殺死

  • 系統會呼叫onSaveInstanceState來儲存當前Activity的狀態,此方法呼叫在onStop之前,與onPause沒有既定的時序關係;
  • 當Activity被重建後,系統會呼叫onRestoreInstanceState,並且把onSave(簡稱)方法所儲存的Bundle物件同時傳參給onRestore(簡稱)和onCreate(),因此可以透過這兩個方法判斷Activity是否被重建,呼叫在onStart之後;
金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

Activity跟window,view之間的關係?

  • Activity在建立時會呼叫 attach() 方法初始化一個PhoneWindow(繼承於Window),每一個Activity都包含了唯一一個PhoneWindow
  • Activity透過setContentView實際上是呼叫的getWindow().setContentView將View設定到PhoneWindow上而PhoneWindow內部是透過WindowManager的addView、removeView、updateViewLayout這三個方法來管理View,WindowManager本質是介面,最終由WindowManagerImpl實現

App的啟動流程

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?
金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

1、點選桌面App圖示,Launcher程式採用Binder IPC向system_server程式發起startActivity請求;
2、system_server程式接收到請求後,向zygote程式傳送建立程式的請求;
3、Zygote程式fork出新的子程式,即App程式;
4、App程式,透過Binder IPC向sytem_server程式發起attachApplication請求;
5、system_server程式在收到請求後,進行一系列準備工作後,再透過binder IPC向App程式傳送scheduleLaunchActivity請求;
6、App程式的binder執行緒(ApplicationThread)在收到請求後,透過handler向主執行緒傳送LAUNCH_ACTIVITY訊息;
7、主執行緒在收到Message後,透過發射機制建立目標Activity,並回撥Activity.onCreate()等方法。

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

最後

面試造火箭,工作擰螺絲。雖然我只想擰螺絲,但是我們卻需要透過造火箭來找到擰螺絲的工作。

有些東西你不僅要懂,而且要能夠很好地表達出來,能夠讓面試官認可你的理解,例如Handler機制,這個是面試必問之題。有些晦澀的點,或許它只活在面試當中,實際工作當中你壓根不會用到它,但是你要知道它是什麼東西。

一些基礎知識和理論肯定是要背的,要理解的背,用自己的語言總結一下背下來。

那麼該如何複習?

我為大家準備了以下一體系的複習資料:

《Android開發七大模組核心知識筆記》

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?
金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

《960全網最全Android開發筆記》

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

《379頁Android開發面試寶典》

歷時半年,我們整理了這份市面上最全面的安卓面試題解析大全
包含了騰訊、百度、小米、阿里、樂視、美團、58、360、新浪、搜狐等一線網際網路公司面試被問到的題目。熟悉本文中列出的知識點會大大增加透過前兩輪技術面試的機率。

如何使用它?

1.可以透過目錄索引直接翻看需要的知識點,查漏補缺。
2.五角星數表示面試問到的頻率,代表重要推薦指數

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

《507頁Android開發相關原始碼解析》

只要是程式設計師,不管是Java還是Android,如果不去閱讀原始碼,只看API文件,那就只是停留於皮毛,這對我們知識體系的建立和完備以及實戰技術的提升都是不利的。

真正最能鍛鍊能力的便是直接去閱讀原始碼,不僅限於閱讀各大系統原始碼,還包括各種優秀的開源庫。

金九銀十Android面試複習題集:關於四大元件中的Activity你瞭解多少?

資料太多,全部展示會影響篇幅,暫時就先列舉這些部分截圖,以上資源均免費分享,以上內容均放在了開源專案: github  中已收錄,大家可以自行獲取(或者關注主頁掃描加微信獲取)。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69983917/viewspace-2722680/,如需轉載,請註明出處,否則將追究法律責任。

相關文章