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

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

又要到金九銀十的跳槽季了,爲了讓更多的小夥伴能夠在面試的時候取的更好的offer,不按期都會分享BAT常問面試題,因爲內容較多,預計閱讀須要....3個月java

今天主要來說一下四大組件中的Activity相關的知識點:android

描述一下Activity 生命週期?

  • onCreate() Activity第-次被建立的時候調用,一些初始化操做能夠在這裏完成。
  • onStart() 這個方法在Activity 由不可見變爲可見的時候調用。
  • onResume() 這個方法在Activity 準備好和用戶進行交互的時候調用。此時的Acivity必定位於返回棧的棧頂,而且處於運行狀態。
  • onPause() 這個方法在系統準備去啓動或者恢復另-個Activity的時候調用。
  • onStop() 這個方法在Activity 徹底不可見的時候調用。它和onPause()方法的主要區別在於,若是啓動的新Activity 是一個對話框式的Activity,那麼onPause()方法會獲得執行,而onStop()方法並不會執行。
  • onDestroy() 這個方法在Activity被銷燬以前調用,以後Activity的狀態將變爲銷燬狀態。
  • onRestart 這個方法在Activity由中止狀態變爲運行狀態以前調用,也就是Activity被從新啓動了。

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

金九銀十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 沒有可複用的實例時是這樣的。github

當 B Activity 的 launchMode 爲 singleTop 且 B Activity 已經在棧頂時(一些特殊狀況如通知欄點擊、連點),此時只有 B 頁面本身有生命週期變化:面試

B.onPause -> B.onNewIntent -> B.onResumeide

當 B Activity 的 launchMode 爲 singleInstance ,singleTask 且對應的 B Activity 有可複用的實例時,生命週期回調是這樣的:佈局

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

Activity的啓動模式

有4種啓動模式:spa

  • 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.java
public 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你瞭解多少?

一、點擊桌面App圖標,Launcher進程採用Binder IPC向system_server進程發起startActivity請求;
二、system_server進程接收到請求後,向zygote進程發送建立進程的請求;
三、Zygote進程fork出新的子進程,即App進程;
四、App進程,經過Binder IPC向sytem_server進程發起attachApplication請求;
五、system_server進程在收到請求後,進行一系列準備工做後,再經過binder IPC向App進程發送scheduleLaunchActivity請求;
六、App進程的binder線程(ApplicationThread)在收到請求後,經過handler向主線程發送LAUNCH_ACTIVITY消息;
七、主線程在收到Message後,經過發射機制建立目標Activity,並回調Activity.onCreate()等方法。

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

最後

面試造火箭,工做擰螺絲。雖然我只想擰螺絲,可是咱們卻須要經過造火箭來找到擰螺絲的工做。

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

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

那麼該如何複習?

我爲你們準備瞭如下一體系的複習資料:

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

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

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

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

《379頁Android開發面試寶典》

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

如何使用它?

1.能夠經過目錄索引直接翻看須要的知識點,查漏補缺。
2.五角星數表示面試問到的頻率,表明重要推薦指數

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

只要是程序員,不論是Java仍是Android,若是不去閱讀源碼,只看API文檔,那就只是停留於皮毛,這對咱們知識體系的創建和完備以及實戰技術的提高都是不利的。

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

資料太多,所有展現會影響篇幅,暫時就先列舉這些部分截圖,以上資源均免費分享,以上內容均放在了開源項目:github 中已收錄,你們能夠自行獲取。

相關文章
相關標籤/搜索