您好,登錄后才能下訂單哦!
每一次去面試就是一次對自我知識的總結和審核,如果你想拿到大廠的offer.成功的通過一面二面三面四面,那么我分享的面試學習路線你可以來參考一下(PDF文檔版見如下)那么面試中最常問的小知識點不懂的透徹怕是不行了
(順手留下GitHub鏈接,需要獲取相關面試等內容的可以自己去找)
https://github.com/xiangjiana/Android-MS
1)Activity: 用戶可操作的可視化界面,為用戶提供一個完成操作指令的窗口。一個 Activity通常是一個單獨的屏幕,Activity通過Intent來進行通信。Android中會維持一個Activity Stack,當一個新 Activity 創建時,它就會放到棧頂,這個 Activity 就處于運行狀態。
2)Service: 服務,運行在手機后臺,適合執行不需和用戶交互且還需長期運行的任務。
3)ContentProvider: 內容提供者,使一個應用程序的指定數據集提供給其他應用程序,其他應用可通過 ContentResolver
類從該內容提供者中獲取或存入數據。它提供了一種跨進程數據共享的方式,當數據被修改后,ContentResolver
接口的 notifyChange
函數通知那些注冊監控特定 URI
的 ContentObserver
對象。
如 果 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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。