快到金三銀四了,不少小夥伴尚未復工,在家呆的有點慌,不知道以後會面臨的裁人仍是被裁人。在這裏我給你們收集了不少面試題,刷完這些面試題,金三銀四絲絕不用慌了
AndroidBAT面試專題PDF+學習筆記+相對應的視頻教程(見末尾)
java
Activity
:onCreate()
->onStart()
->onResume()
->onPause()
->onStop()
->onDestory()
onCreate()
:爲 Activity 設置佈局,此時界面還不可見;onStart()
: Activity 可見但還不能與用戶交互,不能得到焦點onRestart()
: 從新啓動 Activity 時被回調onResume()
: Activity 可見且可與用戶進行交互onPause()
: 當前 Activity 暫停,不可與用戶交互,但還可見。在新 Activity 啓動前被系統調用保存現有的 Activity 中的持久數據、中止動畫等。onStop()
: 當 Activity 被新的 Activity 覆蓋不可見時被系統調用onDestory()
: 當 Activity 被系統銷燬殺掉或是因爲內存不足時調用android
Service
a) onBind
方式綁定的:onCreate
->onBind
->onUnBind
->onDestory
(無論調用 bindService
幾回,onCreate
只會調用一次,onStart
不會被調用,創建鏈接後,service 會一直運行,直到調用unBindService
或是以前調用的 bindService
的 Context 不存在了,系統會自動中止 Service,對
應的 onDestory
會被調用)git
b) startService
啓動的:onCreate
->onStartCommand
->onDestory
(start 屢次,onCreate
只會被
調用一次,onStart
會調用屢次,該service
會在後臺運行,直至被調用stopService
或是stopSelf
)github
c) 又被啓動又被綁定的服務,無論如何調用 onCreate()
只被調用一次,startService
調用多少
次,onStart
就會被調用多少次,而 unbindService
不會中止服務,必須調用 stopService
或是stopSelf
來中止服務。必須 unbindService
和 stopService(stopSelf
)同時都調用了纔會中止服
務。面試
BroadcastReceiver
a) 動態註冊: 存活週期是在 Context.registerReceiver
和 Context.unregisterReceiver
之間,BroadcastReceiver
每次收到廣播都是使用註冊傳入的對象處理的。
b) 靜態註冊: 進程在的狀況下,receiver 會正常收到廣播,調用 onReceive
方法;生命週期
只存活在 onReceive
函數中,此方法結束,BroadcastReceiver
就銷燬了。onReceive()
只有十
幾秒存活時間,在 onReceive()
內操做超過 10S,就會報 ANR。進程不存在的狀況,廣播相應的進程會被拉活,Application.onCreate
會被調用,再調用onReceive
。算法
ContentProvider
:應該和應用的生命週期同樣,它屬於系統應用,應用啓動時,它會跟着初始化,應用關閉或被殺,它會跟着結束。sql
1)經過 Intent 方式傳遞參數跳轉
2)經過廣播方式
3)經過接口回調方式
4)藉助類的靜態變量或全局變量
5)藉助SharedPreference
或是外部存儲,如數據庫或本地文件
1 ) 切 換 橫 屏 時 :onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
2) 切換豎屏時:會打印兩次相同的 logonSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
->onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
數據庫
**3) 如 果 在 AndroidMainfest.xml
中 修 改 該 Activity 的 屬 性 , 添 加android:configChanges="orientation"
橫豎屏切換,打印的 log 同樣,同 1)**
4) 如 果 AndroidMainfest.xml
中 該 Activity 中 的android:configChanges="orientation|keyboardHidden"
,則只會打印onConfigurationChanged
編程
AlertDialog
並不會影響Activity的生命週期,按Home鍵後纔會使Activity走onPause
->onStop
,AlertDialog
只是一個組件,並不會使 Activity 進入後臺設計模式
前一個 Activity 的 onPause
,後一個 Activity 的 onResume
onSaveInstanceState
是哪一個類的方法,在什麼狀況下使用?在對應的 FragmentActivity.onSaveInstanceState
方法會調用 FragmentController.saveAllState
,
其中會對 mActive
中各個 Fragment 的實例狀態和 View 狀態分別進行保存.當 Activity 在作狀
態保存和恢復的時候, 在它其中的 fragment 天然也須要作狀態保存和恢復.
ViewPager+FragmentPagerAdapter+List<Fragment>
1)在相應的 fragment 中編寫方法,在須要回調的 fragment 裏獲取對應的 Fragment 實例,調
用相應的方法;
2)採用接口回調的方式進行數據傳遞;
a) 在Fragment1
中建立一個接口及接口對應的set方法;
b) 在Fragment1
中調用接口的方法;
c)在Fragment2
中實現該接口;
3)利用第三方開源框架 EventBus
ContentProvider
、ContentResolver
、ContentObserver
之間的關係ContentProvider
實現各個應用程序間數據共享,用來提供內容給別的應用操做。如聯繫人應
用中就使用了 ContentProvider
,能夠在本身應用中讀取和修改聯繫人信息,不過須要獲取相
應的權限。它也只是一箇中間件,真正的數據源是文件或 SQLite 等。
ContentResolver
內 容 解 析 者 , 用 於 獲 取 內 容 提 供 者 提 供 的 數 據 , 通 過ContentResolver.notifyChange(uri)
發出消息
ContentObserve
r 內容監聽者,能夠監聽數據的改變狀態,觀察特定 Uri 引發的數據庫變化,
繼而作一些相應的處理,相似於數據庫中的觸發器,當 ContentObserver
所觀察的 Uri 發生
變化時,便會觸發它。
manifest
和代碼中如何註冊和使用 BroadcastReceiver
?1)mainfest
中註冊:靜態註冊的廣播接收者就是一個常駐在系統中的全局監聽器,也就是說
若是你應用中配置了一個靜態的 BroadcastReceiver
,並且你安裝了應用而不管應用是否處於
運行狀態,廣播接收者都是已常常駐在系統中了。
<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="com.smilexie.test.intent.mybroadcastreceiver"/> </intent-filter> </receiver>
2 ) 動態註冊:動態註冊的廣播接收者只有執行了 registerReceiver(receiver, filter)
纔會開始監聽
廣播消息,並對廣播消息做爲相應的處理。
IntentFilter fiter = new IntentFilter("com.smilexie.test.intent.mybroadcastreceiver"); MyBroadcastReceiver receiver = new MyBroadcastReceiver(); registerReceiver(receiver, filter); //撤銷廣播接受者的動態註冊 unregisterReceiver(receiver);
a.layout(left,top,right,bottom)
: 經過修改 View 四個方向的屬性值來修改 View 的座標,從而滑動 View
b.offsetLeftAndRight() offsetTopAndBottom()
: 指定偏移量滑動 view
c.LayoutParams
,改變佈局參數: layoutParams
中保存了 view 的佈局參數,能夠通
過修改佈局參數的方式滑動 view
d.經過動畫來移動 view: 注意安卓的平移動畫不能改變 view 的位置參數,屬性
動畫能夠
e.scrollTo/scrollBy
: 注意移動的是 view 的內容,scrollBy(50,50)
你會看到屏幕上的
內容向屏幕的左上角移動了,這是參考對象不一樣致使的,你能夠看做是它移動的
是手機屏幕,手機屏幕向右下角移動,那麼屏幕上的內容就像左上角移動了
f.scroller
:scroller
須要配置 computeScroll
方法實現 view 的滑動,scroller
自己並不
會滑動 view,它的做用能夠看做一個插值器,它會計算當前時間點 view 應該滑
動到的距離,而後 view 不斷的重繪,不斷的調用 computeScroll
方法,這個方法
是個空方法,因此咱們重寫這個方法,在這個方法中不斷的從 scroller
中獲取當
前 view 的位置,調用 scrollTo
方法實現滑動的效果
點擊事件產生後,首先傳遞給 Activity 的 dispatchTouchEvent
方法,經過PhoneWindow
傳遞給 DecorView
,而後再傳遞給根 ViewGroup
,進入 ViewGroup
的dispatchTouchEvent
方法,執行 onInterceptTouchEvent
方法判斷是否攔截,再不攔截的狀況下,此時會遍歷 ViewGroup
的子元素,進入子 View 的dispatchToucnEvent
方法,若是子 view 設置了 onTouchListener
,就執行onTouch
方法,並根據 onTouch
的返回值爲 true 仍是 false 來決定是否執行 onTouchEvent
方法,若是是 false 則繼續執行 onTouchEvent
,在 onTouchEvent
的 Action Up 事件中判斷,若是設置了 onClickListener
,就執行 onClick
方法。
View 隨着 Activity 的建立而加載,startActivity
啓動一個 Activity 時,在ActivityThread
的handleLaunchActivity
方法中會執行 Activity 的 onCreate
方法,這個時候會調用 setContentView
加載佈局建立出 DecorView
並將咱們的 layout加載到 DecorView
中,當執行到 handleResumeActivity
時,Activity 的 onResume
方法被調用,而後 WindowManager
會將 DecorView
設置給 ViewRootImpl
,這樣,DecorView
就被加載到Window中了,此時界面尚未顯示出來,還須要通過 View的 measure,layout 和 draw 方法,才能完成 View 的工做流程。咱們須要知道 View的繪製是由ViewRoot
來負責的,每個DecorView
都有一個與之關聯的ViewRoot
,這種關聯關係是由WindowManager
維護的,將DecorView
和 ViewRoot
關聯以後,ViewRootImpl
的requestLayout會被調用以完成初步佈局,經過scheduleTraversals
方法向主線程發送消息請求遍歷,最終調用 ViewRootImpl
的 performTraversals
方法,這個方法會執行 View 的 measure layout
和 draw 流程
22)圖片庫對比
23)LRUCache
原理LruCache
是個泛型類,主要原理是:把最近使用的對象用強引用存儲在 LinkedHashMap
中,
當緩存滿時,把最近最少使用的對象從內存中移除,並提供 get/put 方法完成緩存的獲取和
添加。LruCache
是線程安全的,由於使用了 synchronized
關鍵字。當調用 put()方法,將元素加到鏈表頭,若是鏈表中沒有該元素,大小不變,若是沒有,需調用 trimToSize
方法判斷是否超過最大緩存量,trimToSize()
方法中有一個 while(true)
死循環,若是緩存大小大於最大的緩存值,會不斷刪除 LinkedHashMap
中隊尾的元素,即最少訪問的,直到緩存大小小於最大緩存值。當調用 LruCache
的 get 方法時,LinkedHashMap
會調用recordAccess
方法將此元素加到鏈表頭部。
24 )圖片加載原理
25)本身去實現圖片庫,怎麼作?
26) Glide 源碼解析
27) Glide 使用什麼緩存?
1) 內存緩存: LruResourceCache(memory)+
弱引用 activeResources
Map<Key
, WeakReference<EngineResource<?>>> activeResources
正在使用的資源,當 acquired
變量大於 0,說明圖片正在使用,放到 activeResources
弱引用緩存中,通過 release()後,acquired=0
,說明圖片再也不使用,會把它放進 LruResourceCache
中
2)磁盤緩存: DiskLruCache
,這裏分爲 Source(原始圖片)和 Result(轉換後的圖片)
第一次獲取圖片,確定網絡取,而後存 active\disk
中,再把圖片顯示出來,第二次讀取相同
的圖片,並加載到相同大小的 imageview 中,會先從 memory 中取,沒有再去 active 中獲取。
若是 activity 執行到 onStop
時,圖片被回收,active 中的資源會被保存到 memory 中,active
中的資源被回收。當再次加載圖片時,會從 memory 中取,再放入 active 中,並將 memory
中對應的資源回收。
之因此須要 activeResources
,它是一個隨時可能被回收的資源,memory 的強引用頻繁讀寫
可能形成內存激增頻繁 GC,而形成內存抖動。資源在使用過程當中保存在 activeResources
中,
而 activeResources
是弱引用,隨時被系統回收,不會形成內存過多使用和泄漏。
28 )Glide 內存緩存如何控制大小?
Glide 內存緩存最大空間(maxSize)=每一個進程可用最大內存*0.4(低配手機是 每一個進程可用
最大內存*0.33)
磁盤緩存大小是 250MB int DEFAULT_DISK_CACHE_SIZE = 250 1024 1024;
29.網絡框架對比和源碼分析
30.本身去設計網絡請求框架,怎麼作?
31.okhttp 源碼
32.網絡請求緩存處理,okhttp 如何處理網絡緩存的;
33.sqlite 升級,增長字段的語句
34.數據庫框架對比和源碼分析
35.數據庫的優化
36.數據庫數據遷移問題
素?
中。說出最優的方法
71. 談談對 RxJava的理解
RxJava 是基於響應式編程,基於事件流、實現異步操(相似於 Android 中的 AsyncTask
、Handler
做用)做的庫,基於事件流的鏈式調用,使得 RxJava 邏輯簡潔、使用簡單。RxJava 原理是
基於一種擴展的觀察者模式,
有四種角色: 被觀察者 Observable
觀察者 Observer
訂閱subscribe
事件 Event。
RxJava
原理可總結爲: 被觀察者 Observable 經過訂閱(subscribe)按順序發送事件(Emitter)給觀察者(Observer), 觀察者按順序接收事件&做出相應的響應動做
RxJava 中的操做符:
1)defer()
: 直到有觀察者(Observer
)訂閱時,纔會動態建立被觀察者對象(Observer
)&發送事件,經過 Observer
工廠方法建立被觀察者對象,每次訂閱後,都會獲得一個剛建立的最新的
Observer 對象,能夠確保 Observer 對象裏的數據是最新的。defer()
方法只會定義 Observable
對象,只有訂閱操做纔會建立對象。
Observable<T> observable = Observable.defer(new Callable<ObservableSource<? extends T>>() { @Override public ObservableSource<? extends T> call() throws Exception { return Observable.just(); } }
2)timer()
快速建立一個被觀察者(Observable
),延遲指定時間後,再發送事件
Observable.timer(2, TimeUnit.SECONDS)// 也能夠自定義線程 timer(long, TimeUnit, Scheduler) .subscribe(new Observer<Long>() { @Override public void onSubscribe(Disposable d) { } ... });
3) interval() intervalRange()
快速建立一個被觀察者對象(Observable),每隔指定時間就發送
事件
//interval 三個參數,參數 1 :第一次延遲時間 參數 2 :間隔時間數字 參數 3 :時間單位 Observable.interval(3, 1, TimeUnit.SECONDS).subscribe(); //intervalRange 五個參數,參數 1 :事件序列起始點 參數 2 :事件數量 參數 3 :第一次延遲時間 參數 4 :間隔時間數字 參數 5 :時間單位 Observable.intervalRange(3, 10, 2, 1, TimeUnit.SECONDS).subscribe();
1)建立被觀察者對象 Observable&定義須要發送的事件
Observable.create(new ObservableOnSubscribe<T>(){ @Override public void subscribe(ObservableEmitter<T> emitter) throws Exception { // 定義發送事件的行爲 } });
Observable.create()
方法實際建立了一個 ObservableCreate
對象,它是 Observable
的子類,傳
入一個 ObservableOnSubscribe
對象,複寫了發送事件行爲的 subscribe()
方法。
2)建立觀察者對象 Observer&定義響應事件的行爲
Observer observer = new Observer<T>() { @Override public void onSubscribe(Disposable d){//Disposable 對象可用於結束事件 // 默認最早調用 } @Override public void onNext(T t){ } @Override public void onError(Throwable d){ } @Override public void onComplete(){ } }
3)經過 subscribe()
方法使觀察者訂閱被觀察者
Observable.subscribe(Observer observer);// 實際調用的是 ObservableCreate.subscribeActual() 方法,具體實現以下 protected void subscribeActual(Observer<? super T> observer) { // 1. 建立 1 個 CreateEmitter 對象用於發射事件(封裝成 1 個 Disposable 對 象) CreateEmitter<T> parent = new CreateEmitter<T>(observer); // 2. 調用觀察者( Observer )的 onSubscribe () observer.onSubscribe(parent); try { // 3. 調用 source 對象的( ObservableOnSubscribe 對象) subscribe () source.subscribe(parent); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); parent.onError(ex); } }
更多信息能夠點擊關於我 , 很是但願和你們一塊兒交流 , 共同進步
( 順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)