每一次去面試就是一次對自我知識的總結和審覈,若是你想拿到大廠的offer.成功的經過一面二面三面四面,那麼我分享的面試學習路線你能夠來參考一下(PDF文檔版見以下)那麼面試中最常問的小知識點不懂的透徹怕是不行了android
(順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MSgit
1)Activity: 用戶可操做的可視化界面,爲用戶提供一個完成操做指令的窗口。一個 Activity一般是一個單獨的屏幕,Activity經過Intent來進行通訊。Android中會維持一個Activity Stack,當一個新 Activity 建立時,它就會放到棧頂,這個 Activity 就處於運行狀態。
2)Service: 服務,運行在手機後臺,適合執行不需和用戶交互且還需長期運行的任務。
3)ContentProvider: 內容提供者,使一個應用程序的指定數據集提供給其餘應用程序,其餘應用可經過 ContentResolver
類從該內容提供者中獲取或存入數據。它提供了一種跨進程數據共享的方式,當數據被修改後,ContentResolver
接口的 notifyChange
函數通知那些註冊監控特定 URI
的 ContentObserver
對象。github
如 果 ContentProvider
和 調 用 者 在 同 一 進 程 中 , ContentProvider
的 方 法(query/insert/update/delete 等)和調用者在同一線程中;若是ContentProvider
和調用者不在同一進程,ContentProvider
方法會運行在它自身進程的一個 Binder 線程中。面試
4)Broadcast Receiver: 廣播接收者,運用在應用程序間傳輸信息,可使用廣播接收器來讓應用對一個外部事件作出響應。數據庫
1)Activity: onCreate()
->onStart()
->onResume()
->onPause()
->onStop()
->onDestory()
onCreate()
:爲 Activity 設置佈局,此時界面還不可見;onStart()
: Activity 可見但還不能與用戶交互,不能得到焦點onRestart()
: 從新啓動 Activity 時被回調onResume()
: Activity 可見且可與用戶進行交互onPause()
: 當前 Activity 暫停,不可與用戶交互,但還可見。在新 Activity 啓動前被系統調用保存現有的 Activity 中的持久數據、中止動畫等。onStop()
: 當 Activity 被新的 Activity 覆蓋不可見時被系統調用onDestory()
: 當 Activity 被系統銷燬殺掉或是因爲內存不足時調用瀏覽器
a) onBind 方式綁定的: onCreate
->onBind
->onUnBind
->onDestory
(無論調用 bindService
幾回,onCreate
只會調用一次,onStart
不會被調用,創建鏈接後,service 會一直運行,直到調用unBindService
或是以前調用的 bindService
的 Context 不存在了,系統會自動中止 Service,對應的 onDestory
會被調用)安全
b) startService 啓動的: onCreate
->onStartCommand
->onDestory
(start 屢次,onCreate
只會被調用一次,onStart
會調用屢次,該service會在後臺運行,直至被調用stopService
或是stopSelf
)網絡
c) 又被啓動又被綁定的服務,無論如何調用 onCreate()
只被調用一次,startService
調用多少次,onStart
就會被調用多少次,而 unbindService
不會中止服務,必須調用 stopService
或是stopSelf
來中止服務。必須unbindService
和 stopService(stopSelf)
同時都調用了纔會中止服務。框架
a) 動態註冊: 存活週期是在 Context.registerReceiver
和Context.unregisterReceiver
之間,BroadcastReceiver
每次收到廣播都是使用註冊傳入的對象處理的。異步
b) 靜態註冊: 進程在的狀況下,receiver 會正常收到廣播,調用 onReceive
方法;生命週期只存活在 onReceive
函數中,此方法結束BroadcastReceiver
就銷燬了。onReceive()
只有十幾秒存活時間,在 onReceive()
內操做超過 10S,就會報 ANR
。
進程不存在的狀況,廣播相應的進程會被拉活,Application.onCreate
會被調用,再調用onReceive
。
應該和應用的生命週期同樣,它屬於系統應用,應用啓動時,它會跟着初始化,應用關閉或被殺,它會跟着結束。
1)經過 Intent 方式傳遞參數跳轉
2)經過廣播方式
3)經過接口回調方式
4)藉助類的靜態變量或全局變量
5)藉助 SharedPreference 或是外部存儲,如數據庫或本地文件
onPause(A)
->onCreate(B)
->onStart(B)
->onResume(B)
->oStop(A)
這時若是按回退鍵回退到 A onPause(B)
->onRestart(A)
->onStart(A)
->onResume(A)
->oStop(B)
若是在切換到 B 後調用了 A.finish(),則會走到 onDestory(A),這時點回退鍵會退出應用
onPause(A)
->onCreate(B)
->onStart(B)
->onResume(B)
這時若是回退到 A onPause(B)
->onResume(A)
->oStop(B)
->onDestory(B)
onPause(A)
->oStop(A)
->onRestart(A)
->onStart(A)
->onResume(A)
onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
->onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
android:configChanges="orientation"
橫豎屏切換,打印的 log 同樣,同 1)AndroidMainfest.xml
中 該 Activity 中的 android:configChanges="orientation|keyboardHidden"
,則只會打印onConfigurationChanged->
onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
->onPause
->onStop
->onDestoryView
->onDestory
->onDetach
onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
按下 Power 鍵: onPause
->onSaveInstanceState
->onStop
點亮屏幕解鎖: onStart
->onRestoreInstanceState
->onResume
切換到其餘 Fragment: onPause
->onStop
->onDestoryView
切回到該 Fragment: onCreateView
->onActivityCreated
->onStart
->onResume
退出應用: onPause
->onStop
->onDestoryView
->onDestory
->onDetach
AlertDialog
並不會影響Activity的生命週期,按Home鍵後纔會使Activity走onPause
->onStop
,AlertDialog
只是一個組件,並不會使 Activity 進入後臺。
前一個 Activity 的 onPause
,後一個 Activity 的 onResume
1) 前 臺 切 換 到 後 臺 , 會 執 行 onPause
->onStop
再 回 到 前 臺 , 會 執 行onRestart
->onStart
->onResume
2) 彈出 Dialog,並不會影響 Activity 生命週期
標準啓動模式(默認),每啓動一次 Activity,都會建立一個實例,即便從 ActivityAstartActivity
ActivityA
,也會再次建立 A 的實例放於棧頂,當回退時,回到上一個 ActivityA
的實例。
棧頂複用模式,每次啓動 Activity,若是待啓動的 Activity 位於棧頂,則不會從新 創 建 Activity 的 實 例 , 即 不 會 走 onCreate
->onStart
, 會 直 接 進 入 Activity 的onPause
->onNewIntent
->onResume
方法
單一實例模式,整個手機操做系統裏只有一個該 Activity 實例存在,沒有
其餘 Actvity,後續請求均不會建立新的 Activity。若 task 中存在實例,執行實例的onNewIntent()
。
應用場景: 鬧鐘、瀏覽器、電話
棧內複用,啓動的 Activity 若是在指定的 taskAffinity
的 task 棧中存在相應的實例,則會把它上面的 Activity 都出棧,直到當前 Activity 實例位於棧頂,執行相應的onNewIntent()
方法。若是指定的 task 不存在,建立指定的taskAffinity
的 task,taskAffinity
的做用,進入指寫 taskAffinity
的 task,若是指定的 task 存在,將 task 移到前臺,若是指定的 task不存在,建立指定的 taskAffinity
的 task.
應用場景:應用的主頁面
Activity 被主動回收時,如按下 Back 鍵,系統不會保存它的狀態,只有被動回收時,雖然這個 Activity 實例已被銷燬,但系統在新建一個 Activity 實例時,會帶上先前被回收 Activity 的信息。在當前 Activity 被銷燬前調用onSaveInstanceState
(onPause
和 onStop
之間保存),從新建立 Activity 後會在 onCreate
後調用onRestoreInstanceState
(onStart
和onResume
之間被調用),它們的參數 Bundle 用來數據保存和讀取的。
保存 View 狀態有兩個前提:View 的子類必須實現了 onSaveInstanceState
; 必需要設定 Id,這個 ID 做爲 Bundle 的 Key
onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
->onPause
->onStop
->onDestoryView
->onDestory
->onDetach
Fragment 在 Activity 中replace onPause(舊)
->onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
->onStop(舊)
->onDestoryView(舊)
若是添加到 backStack
中,調用 remove()方法 fragment 的方法會走到onDestoryView
,但不會執行 onDetach()
,即 fragment 自己的實例是存在的,成員變量也存在,可是 view 被銷燬了。若是新替換的 Fragment 已在 BackStack
中,則不會執行 onAttach
->onCreate
在對應的 FragmentActivity.onSaveInstanceState
方法會調用FragmentController.saveAllState
,其中會對 mActive
中各個 Fragment 的實例狀態和 View 狀態分別進行保存.當 Activity 在作狀態保存和恢復的時候, 在它其中的 fragment 天然也須要作狀態保存和恢復.
若是但願在 Fragment 的onActivityResult
接收數據,就要調用Fragment.startActivityForResult
,而 不 是 Fragment.getActivity().startActivityForResult
。Fragment.startActivityForResult
->FragmentActivitymHost.HostCallbacks.onStartActivityFromFragment
->FragmentActivity.startActivityFromFragment
。 如 果 request=-1 則 直 接 調 用FragmentActivity.startActivityForResult
,它會從新計算 requestCode
,使其大於0xfffff。
ViewPager+FragmentPagerAdapter+List<Fragment>
1) 在相應的 fragment 中編寫方法,在須要回調的 fragment 裏獲取對應的 Fragment 實例,調用相應的方法;
2) 採用接口回調的方式進行數據傳遞;
a) 在Fragment1中建立一個接口及接口對應的set方法; b) 在Fragment1中調用接口的方法;
c)在 Fragment2 中實現該接口;
3) 利用第三方開源框架 EventBus
1) 經過 bindService
啓動服務,能夠在 ServiceConnection
的onServiceConnected
中獲取到Service 的實例,這樣就能夠調用 service 的方法,若是 service 想調用 activity 的方法,能夠在 service 中定義接口類及相應的 set 方法,在 activity 中實現相應的接口,這樣 service 就能夠回調接口言法;
2) 經過廣播方式
ContentProvider
實現各個應用程序間數據共享,用來提供內容給別的應用操做。如聯繫人應用中就使用了 ContentProvider
,能夠在本身應用中讀取和修改聯繫人信息,不過須要獲取相應的權限。它也只是一箇中間件,真正的數據源是文件或 SQLite
等。
ContentResolver
內 容 解 析 者 , 用 於 獲 取 內 容 提 供 者 提 供 的 數 據 , 通 過ContentResolver.notifyChange(uri)
發出消息
ContentObserver
內容監聽者,能夠監聽數據的改變狀態,觀察特定 Uri 引發的數據庫變化,繼而作一些相應的處理,相似於數據庫中的觸發器,當 ContentObserver
所觀察的 Uri 發生變化時,便會觸發它。
BroadcastReceiver
是一種全局監聽器,用來實現系統中不一樣組件之間的通訊。有時候也會用來做爲傳輸少許並且發送頻率低的數據,可是若是數據的發送頻率比較高或者數量比較大就不建議用廣播接收者來接收了,由於這樣的效率很很差,由於 BroadcastReceiver
接收數據的開銷仍是比較大的。
1 )普通廣播: 徹底異步的,能夠在同一時刻(邏輯上)被全部接收者接收到,消息傳遞的效率比較高,而且沒法中斷廣播的傳播。
2 ) 有序廣播: 發送有序廣播後,廣播接收者將按預先聲明的優先級依次接收 Broadcast。優先級高的優先接收到廣播,而在其 onReceiver()
執行過程當中,廣播不會傳播到下一個接收者,此時當前的廣播接收者能夠abortBroadcast()
來終止廣播繼續向下傳播,也能夠將 intent 中的數據進行修改設置,而後將其傳播到下一個廣播接收者。sendOrderedBroadcast(intent,null);//
發送有序廣播
3 )粘性廣播: sendStickyBroadcast()
來發送該類型的廣播信息,這種的廣播的最大特色是,當粘性廣播發送後,最後的一個粘性廣播會滯留在操做系統中。若是在粘性廣播發送後的一段時間裏,若是有新的符合廣播的動態註冊的廣播接收者註冊,將會收到這個廣播消息,雖然這個廣播是在廣播接收者註冊以前發送的,另一點,對於靜態註冊的廣播接收者來講,這個等同於普通廣播。
在 AndroidManifest
中靜態註冊的廣播接收器,通常咱們在收到該消息後,
須要作一些相應的動做,而這些動做與當前 App 的組件,好比 Activity 或者 Service 的是否運行無關,好比咱們在集成第三方 Push SDK 時,通常都會添加一個靜態註冊的BroadcastReceiver
來監聽 Push 消息,當有 Push 消息過來時,會在後臺作一些網絡請求或者發送通知等等。
這種主要是在 Activity 或者 Service 中使用 registerReceiver()
動態註冊的廣
播接收器,由於當咱們收到一些特定的消息,好比網絡鏈接發生變化時,咱們可能須要在當前 Activity 頁面給用戶一些 UI 上的提示,或者將 Service 中的網絡請求任務暫停。因此這種動態註冊的廣播接收器適合特定組件的特定消息處理。
靜態註冊的廣播接收者就是一個常駐在系統中的全局監聽器,也就是說若是你應用中配置了一個靜態的 BroadcastReceiver,並且你安裝了應用而不管應用是否處於運行狀態,廣播接收者都是已常常駐在系統中了。
<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <actionandroid:name="com.smilexie.test.intent.mybroadcastreceiver"/> </intent-filter> </receiver>
動態註冊的廣播接收者只有執行了registerReceiver
(receiver, filter)纔會開始監聽廣播消息,並對廣播消息做爲相應的處理。
IntentFilter fiter = newIntentFilter("com.smilexie.test.intent.mybroadcastreceiver"); MyBroadcastReceiver receiver = new MyBroadcastReceiver(); registerReceiver(receiver, filter); //撤銷廣播接受者的動態註冊unregisterReceiver(receiver);
1) LocalBroadcastReceiver
僅在本身的應用內發送接收廣播,也就是隻有本身的應用能收到,數據更加安全。廣播只在這個程序裏,並且效率更高。只能動態註冊,在發送和註冊的時候採用 LocalBroadcastManager
的 sendBroadcast
方法和 registerReceiver
方法。
2)全局廣播: 發送的廣播事件可被其餘應用程序獲取,也能響應其餘應用程序發送的廣播事件(能夠經過 exported–是否監聽其餘應用程序發送的廣播 在清單文件中控制) 全局廣播既能夠動態註冊,也能夠靜態註冊。
(1)Popupwindow
在顯示以前必定要設置寬高,Dialog 無此限制。
(2)Popupwindow
默認不會響應物理鍵盤的 back,除非顯示設置了 popup.setFocusable(true)
;而在點擊 back 的時候,Dialog 會消失。
(3)Popupwindow
不會給頁面其餘的部分添加蒙層,而 Dialog 會。
(4) Popupwindow
沒 有 標 題 , Dialog 默 認 有 標 題 , 可 以 通 過dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
取消標題
(5)兩者顯示的時候都要設置 Gravity。若是不設置,Dialog 默認是Gravity.CENTER。
(6) 二 者 都 有 默 認 的 背 景 , 都 可 以 通 過setBackgroundDrawable(newColorDrawable(android.R.color.transparent));
去掉。
(7)Popupwindow
彈出後,取得了用戶操做的響應處理權限,使得其餘 UI 控件不被觸發。而 AlertDialog
彈出後,點擊背景,AlertDialog
會消失。
1)Application Context
是伴隨應用生命週期;不能夠 showDialog
, startActivity
, LayoutInflation
能夠startService\BindService\sendBroadcast\registerBroadcast\load Resource values
2)Activity Context
指生命週期只與當前 Activity 有關,而 Activity Context
這些操做均可以,即凡是跟 UI 相關的,都得用 Activity 作爲 Context 來處理。
一個應用 Context 的數量=Activity 數量+Service 數量+1(Application 數量)
(順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS