每一次去面試就是一次對自我知識的總結(jié)和審核,如果你想拿到大廠的offer.成功的通過一面二面三面四面,那么我分享的面試學習路線你可以來參考一下(PDF文檔版見如下)那么面試中最常問的小知識點不懂的透徹怕是不行了
創(chuàng)新互聯(lián)建站,專注為中小企業(yè)提供官網(wǎng)建設、營銷型網(wǎng)站制作、成都響應式網(wǎng)站建設公司、展示型成都網(wǎng)站建設、成都網(wǎng)站設計等服務,幫助中小企業(yè)通過網(wǎng)站體現(xiàn)價值、有效益。幫助企業(yè)快速建站、解決網(wǎng)站建設與網(wǎng)站營銷推廣問題。
(順手留下GitHub鏈接,需要獲取相關面試等內(nèi)容的可以自己去找)
https://github.com/xiangjiana/Android-MS
1)Activity:用戶可操作的可視化界面,為用戶提供一個完成操作指令的窗口。一個 Activity通常是一個單獨的屏幕,Activity通過Intent來進行通信。Android中會維持一個Activity Stack,當一個新 Activity 創(chuàng)建時,它就會放到棧頂,這個 Activity 就處于運行狀態(tài)。
2)Service:服務,運行在手機后臺,適合執(zhí)行不需和用戶交互且還需長期運行的任務。
3)ContentProvider:內(nèi)容提供者,使一個應用程序的指定數(shù)據(jù)集提供給其他應用程序,其他應用可通過 ContentResolver
類從該內(nèi)容提供者中獲取或存入數(shù)據(jù)。它提供了一種跨進程數(shù)據(jù)共享的方式,當數(shù)據(jù)被修改后,ContentResolver
接口的 notifyChange
函數(shù)通知那些注冊監(jiān)控特定 URI
的 ContentObserver
對象。
如 果 ContentProvider
和 調(diào) 用 者 在 同 一 進 程 中 , ContentProvider
的 方 法(query/insert/update/delete 等)和調(diào)用者在同一線程中;如果ContentProvider
和調(diào)用者不在同一進程,ContentProvider
方法會運行在它自身進程的一個 Binder 線程中。
4)Broadcast Receiver:廣播接收者,運用在應用程序間傳輸信息,可以使用廣播接收器來讓應用對一個外部事件做出響應。
1)Activity:onCreate()
->onStart()
->onResume()
->onPause()
->onStop()
->onDestory()
onCreate()
:為 Activity 設置布局,此時界面還不可見;onStart()
: Activity 可見但還不能與用戶交互,不能獲得焦點onRestart()
: 重新啟動 Activity 時被回調(diào)onResume()
: Activity 可見且可與用戶進行交互onPause()
: 當前 Activity 暫停,不可與用戶交互,但還可見。在新 Activity 啟動前被系統(tǒng)調(diào)用保存現(xiàn)有的 Activity 中的持久數(shù)據(jù)、停止動畫等。onStop()
: 當 Activity 被新的 Activity 覆蓋不可見時被系統(tǒng)調(diào)用onDestory()
: 當 Activity 被系統(tǒng)銷毀殺掉或是由于內(nèi)存不足時調(diào)用
a) onBind 方式綁定的:onCreate
->onBind
->onUnBind
->onDestory
(不管調(diào)用 bindService
幾次,onCreate
只會調(diào)用一次,onStart
不會被調(diào)用,建立連接后,service 會一直運行,直到調(diào)用unBindService
或是之前調(diào)用的 bindService
的 Context 不存在了,系統(tǒng)會自動停止 Service,對應的 onDestory
會被調(diào)用)
b) startService 啟動的:onCreate
->onStartCommand
->onDestory
(start 多次,onCreate
只會被調(diào)用一次,onStart
會調(diào)用多次,該service會在后臺運行,直至被調(diào)用stopService
或是stopSelf
)
c)又被啟動又被綁定的服務,不管如何調(diào)用 onCreate()
只被調(diào)用一次,startService
調(diào)用多少次,onStart
就會被調(diào)用多少次,而 unbindService
不會停止服務,必須調(diào)用 stopService
或是stopSelf
來停止服務。必須unbindService
和 stopService(stopSelf)
同時都調(diào)用了才會停止服務。
a) 動態(tài)注冊:存活周期是在 Context.registerReceiver
和Context.unregisterReceiver
之間,BroadcastReceiver
每次收到廣播都是使用注冊傳入的對象處理的。
b) 靜態(tài)注冊:進程在的情況下,receiver 會正常收到廣播,調(diào)用 onReceive
方法;生命周期只存活在 onReceive
函數(shù)中,此方法結(jié)束BroadcastReceiver
就銷毀了。onReceive()
只有十幾秒存活時間,在 onReceive()
內(nèi)操作超過 10S,就會報 ANR
。
進程不存在的情況,廣播相應的進程會被拉活,Application.onCreate
會被調(diào)用,再調(diào)用onReceive
。
應該和應用的生命周期一樣,它屬于系統(tǒng)應用,應用啟動時,它會跟著初始化,應用關閉或被殺,它會跟著結(jié)束。
1)通過 Intent 方式傳遞參數(shù)跳轉(zhuǎn)
2)通過廣播方式
3)通過接口回調(diào)方式
4)借助類的靜態(tài)變量或全局變量
5)借助 SharedPreference 或是外部存儲,如數(shù)據(jù)庫或本地文件
onPause(A)
->onCreate(B)
->onStart(B)
->onResume(B)
->oStop(A)
這時如果按回退鍵回退到 A onPause(B)
->onRestart(A)
->onStart(A)
->onResume(A)
->oStop(B)
如果在切換到 B 后調(diào)用了 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)前 臺 切 換 到 后 臺 , 會 執(zhí) 行 onPause
->onStop
再 回 到 前 臺 , 會 執(zhí) 行onRestart
->onStart
->onResume
2)彈出 Dialog,并不會影響 Activity 生命周期
標準啟動模式(默認),每啟動一次 Activity,都會創(chuàng)建一個實例,即使從 ActivityAstartActivity
ActivityA
,也會再次創(chuàng)建 A 的實例放于棧頂,當回退時,回到上一個 ActivityA
的實例。
棧頂復用模式,每次啟動 Activity,如果待啟動的 Activity 位于棧頂,則不會重新 創(chuàng) 建 Activity 的 實 例 , 即 不 會 走 onCreate
->onStart
, 會 直 接 進 入 Activity 的onPause
->onNewIntent
->onResume
方法
單一實例模式,整個手機操作系統(tǒng)里只有一個該 Activity 實例存在,沒有
其他 Actvity,后續(xù)請求均不會創(chuàng)建新的 Activity。若 task 中存在實例,執(zhí)行實例的onNewIntent()
。
應用場景:鬧鐘、瀏覽器、電話
棧內(nèi)復用,啟動的 Activity 如果在指定的 taskAffinity
的 task 棧中存在相應的實例,則會把它上面的 Activity 都出棧,直到當前 Activity 實例位于棧頂,執(zhí)行相應的onNewIntent()
方法。如果指定的 task 不存在,創(chuàng)建指定的taskAffinity
的 task,taskAffinity
的作用,進入指寫 taskAffinity
的 task,如果指定的 task 存在,將 task 移到前臺,如果指定的 task不存在,創(chuàng)建指定的 taskAffinity
的 task.
應用場景:應用的主頁面
Activity 被主動回收時,如按下 Back 鍵,系統(tǒng)不會保存它的狀態(tài),只有被動回收時,雖然這個 Activity 實例已被銷毀,但系統(tǒng)在新建一個 Activity 實例時,會帶上先前被回收 Activity 的信息。在當前 Activity 被銷毀前調(diào)用onSaveInstanceState
(onPause
和 onStop
之間保存),重新創(chuàng)建 Activity 后會在 onCreate
后調(diào)用onRestoreInstanceState
(onStart
和onResume
之間被調(diào)用),它們的參數(shù) Bundle 用來數(shù)據(jù)保存和讀取的。
保存 View 狀態(tài)有兩個前提:View 的子類必須實現(xiàn)了 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
中,調(diào)用 remove()方法 fragment 的方法會走到onDestoryView
,但不會執(zhí)行 onDetach()
,即 fragment 本身的實例是存在的,成員變量也存在,但是 view 被銷毀了。如果新替換的 Fragment 已在 BackStack
中,則不會執(zhí)行 onAttach
->onCreate
在對應的 FragmentActivity.onSaveInstanceState
方法會調(diào)用FragmentController.saveAllState
,其中會對 mActive
中各個 Fragment 的實例狀態(tài)和 View 狀態(tài)分別進行保存.當 Activity 在做狀態(tài)保存和恢復的時候, 在它其中的 fragment 自然也需要做狀態(tài)保存和恢復.
如果希望在 Fragment 的onActivityResult
接收數(shù)據(jù),就要調(diào)用Fragment.startActivityForResult
,而 不 是 Fragment.getActivity().startActivityForResult
。Fragment.startActivityForResult
->FragmentActivitymHost.HostCallbacks.onStartActivityFromFragment
->FragmentActivity.startActivityFromFragment
。 如 果 request=-1 則 直 接 調(diào) 用FragmentActivity.startActivityForResult
,它會重新計算 requestCode
,使其大于0xfffff。
ViewPager+FragmentPagerAdapter+List
1)在相應的 fragment 中編寫方法,在需要回調(diào)的 fragment 里獲取對應的 Fragment 實例,調(diào)用相應的方法;
2)采用接口回調(diào)的方式進行數(shù)據(jù)傳遞;
a) 在Fragment1中創(chuàng)建一個接口及接口對應的set方法; b) 在Fragment1中調(diào)用接口的方法;
c)在 Fragment2 中實現(xiàn)該接口;
3)利用第三方開源框架 EventBus
1)通過 bindService
啟動服務,可以在 ServiceConnection
的onServiceConnected
中獲取到Service 的實例,這樣就可以調(diào)用 service 的方法,如果 service 想調(diào)用 activity 的方法,可以在 service 中定義接口類及相應的 set 方法,在 activity 中實現(xiàn)相應的接口,這樣 service 就可以回調(diào)接口言法;
2)通過廣播方式
ContentProvider
實現(xiàn)各個應用程序間數(shù)據(jù)共享,用來提供內(nèi)容給別的應用操作。如聯(lián)系人應用中就使用了 ContentProvider
,可以在自己應用中讀取和修改聯(lián)系人信息,不過需要獲取相應的權(quán)限。它也只是一個中間件,真正的數(shù)據(jù)源是文件或 SQLite
等。
ContentResolver
內(nèi) 容 解 析 者 , 用 于 獲 取 內(nèi) 容 提 供 者 提 供 的 數(shù) 據(jù) , 通 過ContentResolver.notifyChange(uri)
發(fā)出消息
ContentObserver
內(nèi)容監(jiān)聽者,可以監(jiān)聽數(shù)據(jù)的改變狀態(tài),觀察特定 Uri 引起的數(shù)據(jù)庫變化,繼而做一些相應的處理,類似于數(shù)據(jù)庫中的觸發(fā)器,當 ContentObserver
所觀察的 Uri 發(fā)生變化時,便會觸發(fā)它。
BroadcastReceiver
是一種全局監(jiān)聽器,用來實現(xiàn)系統(tǒng)中不同組件之間的通信。有時候也會用來作為傳輸少量而且發(fā)送頻率低的數(shù)據(jù),但是如果數(shù)據(jù)的發(fā)送頻率比較高或者數(shù)量比較大就不建議用廣播接收者來接收了,因為這樣的效率很不好,因為 BroadcastReceiver
接收數(shù)據(jù)的開銷還是比較大的。
1 )普通廣播:完全異步的,可以在同一時刻(邏輯上)被所有接收者接收到,消息傳遞的效率比較高,并且無法中斷廣播的傳播。
2 ) 有序廣播:發(fā)送有序廣播后,廣播接收者將按預先聲明的優(yōu)先級依次接收 Broadcast。優(yōu)先級高的優(yōu)先接收到廣播,而在其 onReceiver()
執(zhí)行過程中,廣播不會傳播到下一個接收者,此時當前的廣播接收者可以abortBroadcast()
來終止廣播繼續(xù)向下傳播,也可以將 intent 中的數(shù)據(jù)進行修改設置,然后將其傳播到下一個廣播接收者。sendOrderedBroadcast(intent,null);//
發(fā)送有序廣播
3 )粘性廣播:sendStickyBroadcast()
來發(fā)送該類型的廣播信息,這種的廣播的最大特點是,當粘性廣播發(fā)送后,最后的一個粘性廣播會滯留在操作系統(tǒng)中。如果在粘性廣播發(fā)送后的一段時間里,如果有新的符合廣播的動態(tài)注冊的廣播接收者注冊,將會收到這個廣播消息,雖然這個廣播是在廣播接收者注冊之前發(fā)送的,另外一點,對于靜態(tài)注冊的廣播接收者來說,這個等同于普通廣播。
在 AndroidManifest
中靜態(tài)注冊的廣播接收器,一般我們在收到該消息后,
需要做一些相應的動作,而這些動作與當前 App 的組件,比如 Activity 或者 Service 的是否運行無關,比如我們在集成第三方 Push SDK 時,一般都會添加一個靜態(tài)注冊的BroadcastReceiver
來監(jiān)聽 Push 消息,當有 Push 消息過來時,會在后臺做一些網(wǎng)絡請求或者發(fā)送通知等等。
這種主要是在 Activity 或者 Service 中使用 registerReceiver()
動態(tài)注冊的廣
播接收器,因為當我們收到一些特定的消息,比如網(wǎng)絡連接發(fā)生變化時,我們可能需要在當前 Activity 頁面給用戶一些 UI 上的提示,或者將 Service 中的網(wǎng)絡請求任務暫停。所以這種動態(tài)注冊的廣播接收器適合特定組件的特定消息處理。
靜態(tài)注冊的廣播接收者就是一個常駐在系統(tǒng)中的全局監(jiān)聽器,也就是說如果你應用中配置了一個靜態(tài)的 BroadcastReceiver,而且你安裝了應用而無論應用是否處于運行狀態(tài),廣播接收者都是已經(jīng)常駐在系統(tǒng)中了。
動態(tài)注冊的廣播接收者只有執(zhí)行了registerReceiver
(receiver, filter)才會開始監(jiān)聽廣播消息,并對廣播消息作為相應的處理。
IntentFilter fiter = newIntentFilter("com.smilexie.test.intent.mybroadcastreceiver");
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
registerReceiver(receiver, filter);
//撤銷廣播接受者的動態(tài)注冊unregisterReceiver(receiver);
1)LocalBroadcastReceiver
僅在自己的應用內(nèi)發(fā)送接收廣播,也就是只有自己的應用能收到,數(shù)據(jù)更加安全。廣播只在這個程序里,而且效率更高。只能動態(tài)注冊,在發(fā)送和注冊的時候采用 LocalBroadcastManager
的 sendBroadcast
方法和 registerReceiver
方法。
2)全局廣播:發(fā)送的廣播事件可被其他應用程序獲取,也能響應其他應用程序發(fā)送的廣播事件(可以通過 exported–是否監(jiān)聽其他應用程序發(fā)送的廣播 在清單文件中控制) 全局廣播既可以動態(tài)注冊,也可以靜態(tài)注冊。
(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
彈出后,取得了用戶操作的響應處理權(quán)限,使得其他 UI 控件不被觸發(fā)。而 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 的數(shù)量=Activity 數(shù)量+Service 數(shù)量+1(Application 數(shù)量)
(順手留下GitHub鏈接,需要獲取相關面試等內(nèi)容的可以自己去找)
https://github.com/xiangjiana/Android-MS