又要到金九銀十的跳槽季了,爲了讓更多的小夥伴能夠在面試的時候取的更好的offer,不按期都會分享BAT常問面試題,因爲內容較多,預計閱讀須要....3個月java
今天主要來說一下四大組件中的Activity相關的知識點:android
生命週期:爲了鞏固記憶,畫了一遍。git
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
有4種啓動模式:spa
標準模式:每次啓動時,都會建立一個新的實例在棧頂
棧頂複用模式:若是須要新建立的實例就在棧頂,那麼就不會去重建,而是重用,不然就從新建立。
棧內複用模式:若是實例在當前棧中已經存在,就會將當前實例上面的其餘實例都移除棧。
單例模式:直接建立一個新的棧而且建立實例放在棧中。
使用方式:
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上
那麼這兩種方式有什麼區別呢?
Activity的生命週期中,大部分都是兩兩相對的,能夠將其分爲3種,前臺,可見,後臺。 onStart,onStop之間所經歷的是可見的,可是卻可能沒法與用戶交互。 onResume,onPause之間所經歷的是屬於前臺,這時候用戶是能夠交互的。
不會!
鎖屏時只會調用onPause(),而不會調用onStop方法,開屏後則調用onResume()。
若是清單文件中沒有設置android:configChanges屬性時,生命週期:先銷燬onPause()、onStop()、onDestroy()再從新建立onCreate()、onStart()、onResume()方法。
設置orientation|screenSize(必定要同時出現)屬性值時,不走生命週期方法,只會執行onConfigurationChanged()方法。
咱們知道,生命週期回調都是 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 的佈局通常都是在 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 不屬於 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
ANR 的四種場景:
咱們能夠看到,Activity 的生命週期回調的阻塞並不在觸發 ANR 的場景裏面,因此並不會直接觸發 ANR。
只不過死循環阻塞了主線程,若是系統再有上述的四種事件發生,就沒法在相應的時間內處理從而觸發 ANR。
若是須要啓動的實例是以前有打開過的,而且在棧的頂部,目前處於onPause、onStop 的狀態,其餘實例再次進入的話,執行順序爲:onNewIntent,onRestart,onStart,onResume。
異常狀況下系統配置發生改變時致使Activity被殺死並從新建立、資源內存不足致使低優先級的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()等方法。
面試造火箭,工做擰螺絲。雖然我只想擰螺絲,可是咱們卻須要經過造火箭來找到擰螺絲的工做。
有些東西你不只要懂,並且要可以很好地表達出來,可以讓面試官承認你的理解,例如Handler機制,這個是面試必問之題。有些晦澀的點,或許它只活在面試當中,實際工做當中你壓根不會用到它,可是你要知道它是什麼東西。
一些基礎知識和理論確定是要背的,要理解的背,用本身的語言總結一下背下來。
我爲你們準備瞭如下一體系的複習資料:
《Android開發七大模塊核心知識筆記》
《960全網最全Android開發筆記》
《379頁Android開發面試寶典》
歷時半年,咱們整理了這份市面上最全面的安卓面試題解析大全
包含了騰訊、百度、小米、阿里、樂視、美團、5八、獵豹、360、新浪、搜狐等一線互聯網公司面試被問到的題目。熟悉本文中列出的知識點會大大增長經過前兩輪技術面試的概率。
如何使用它?
1.能夠經過目錄索引直接翻看須要的知識點,查漏補缺。
2.五角星數表示面試問到的頻率,表明重要推薦指數
《507頁Android開發相關源碼解析》
只要是程序員,不論是Java仍是Android,若是不去閱讀源碼,只看API文檔,那就只是停留於皮毛,這對咱們知識體系的創建和完備以及實戰技術的提高都是不利的。
真正最能鍛鍊能力的即是直接去閱讀源碼,不只限於閱讀各大系統源碼,還包括各類優秀的開源庫。
資料太多,所有展現會影響篇幅,暫時就先列舉這些部分截圖,以上資源均免費分享,以上內容均放在了開源項目:【github】 中已收錄,你們能夠自行獲取。