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