【最新Android高級面試知識點乾貨分享(五)】
轉載請註明出處!
六、Android自定義View
更深入一點的,應該瞭解一下WMS,以及View與Window、Activity之間是怎麼關聯,怎麼添加上去的。針對View,還得了解它的測量模式與測量規範。
- 延伸:從源碼角度分析View的繪製流程(onAttach–onMeasure—onLayout—onDraw)
針對Android繪圖機制,推薦下面2篇文章,加深理解記憶:
$6.1、Activity、Window/PhoneWindow、View、ViewRootImpl、DecorView的關係
下面這圖是我自己根據源碼畫的圖:從Activity啓動開始,WMS是如何把View添加到窗口上且與Activity相關起來的。
下面這圖來源於網絡,清楚的展現出了Activity、PhoneWindow/Window、DecorView三者之間的關係。
七、Android 動畫繪製原理
$7.1、 Android屏幕刷新機制
-
每隔16.6ms刷新一次屏幕(即每幀【每一屏幕】繪製時間大致爲16.6ms:理想狀態下,每秒展示不低於60幀(FPS)時纔會感覺不到卡頓 ,即一幀屏幕繪製完耗時:1000ms/60fps = 16.6ms)
-
幀的渲染過程(下圖來源於google開發者文檔)
參考博客:https://www.jianshu.com/p/280ec5c566ea
$7.2、典型的顯示系統:CPU、GPU、Buffer
(只有一個緩衝,又稱單緩衝)
-
顯示器重要特性:
- 行頻(HSYNC:水平掃描頻率Horizontal Scanning Frequency):HSYNC脈衝信號爲高電平時,將告訴系統該掃描下一行了,即要轉到下一行起始處了。
- 場頻(VSYNC:垂直掃描頻率Vertical Scanning Frequency):由於屏幕是先從左至右掃描,再垂直掃描,因此場頻也是作爲屏幕刷新完畢的條件,即每秒屏幕刷新的的次數。
- 行頻 = 場頻 * 縱座標分辨率
(下圖來源於網絡)
-
VSync(VerticalSynchronization)垂直同步:
當屏幕從左至右,從上到下掃描一次完畢後,又將從頭開始,進入下一次循環。
這時有一段時間空隙,叫做VBI(VerticalBlankingInterval)。
因爲此時屏幕沒有在刷新,這個時間點就是我們進行緩衝區交換的最佳時間,也就避免了交換過程中出現 screentearing的狀況
VSync是屬於脈衝信號,由高低電平來控制類似開關的操作。因此在VBI時,底層硬件發出VSync脈衝信號,來進行緩衝區數據的交互。
DoubleBuffer雙緩衝系統:
Triple Buffer三級緩衝:
與雙緩衝差不多,就是多了一個BackBuffer.
$7.3、 View動畫(Tween Animation 補間動畫)
參考文章:https://www.jianshu.com/p/48317612c164
-
View.startAnimation(mAnimation):
調用此方法時,並不會立即開始動畫,startAnimation方法裏面會去遍歷View樹,調用draw()方法進行繪製,最終執行動畫的方法是在draw()方法裏面 -
主要執行流程圖:
記住一點:
View動畫最後執行的原理爲Matrix矩陣變換。比如:平移、縮放、旋轉,Alpha漸變等。變換的是parentView,也就是ViewGroup,但對其他沒影響。因此View動畫纔不會改變view的屬性。
$7.4、 屬性動畫(Property Animator)
-
工作原理
在一定時間間隔內,通過不斷對值進行改變,並不斷將該值賦給對象的屬性,從而實現該對象在該屬性上的動畫效果 -
執行流程圖
屬性動畫在原理上與視圖動畫有很大的區別。屬性動畫是利用顯示系統原理來進行渲染顯示。在Android中主要是利用SurfaceFlinger 與 Choreographer來接收VSnc垂直同步信號,通過幀回調來刷新界面顯示。 -
SurfaceFlinger:用於接收各種數據,並組進行組合,之後將結果存入FrameBuffer中。以便Display顯示系統從中獲取。類似【編劇】
-
Choreographer:編舞者。用於對View的編排。由ViewRootImpl持有。當接收到VSnc信號時,就會執行回調方法,
參考網上的圖:
-
插值器(Interpolator)
- 1,一個輔助動畫實現的接口;
- 2,設置屬性值 從“初始值” 【過渡】到“結束值”的變化規律(如:勻速、加速、減速、先加速後減速、先減速後加速。可根據需要的變化規律進行自定義插值器);
- 3、系統內置插值器:
- LinearInterpolator(線性插值器):動畫勻速改變
- DecelerateInterpolator(減速插值器):動畫高速開始,減速運行
- AccelerateInterpolator(加速插值器):動畫低速開始,加速運行
- AccelerateDecelerateInterpolator:先加速後減速
- AnticipateInterpolator:先退後,再加速向前至終點結束
- AnticipateOvershootInterpolator:先退後,再加速先進,越過終點後,再返回終點
- BounceInterpolator:到達終點後,再回彈,至靜止
- CycleInterpolator:週期運動(動畫可以不到終點就回彈,也可以到了終點後在回彈,還可以回彈多次,小於1.0f不到終點就回彈,大於1.0f會到了終點後回彈,如果大於2,則會回彈多次)
- OvershootInterpolator:快速完成動畫,會超出一點然後再回到結束樣式
- PathInterpolator:根據路徑來控制動畫的執行快慢,路徑可以是貝塞爾曲線,也可以是普通Path。
-
估值器(TypeEvaluator)
- 1,一個輔助動畫插值器實現的接口;
- 2,設置屬性值 在從初始值過渡到結束值的變化規律中的過渡值。(如:從0 過渡到1時,估值器會根據給定的插值器變化規律,估算出0~1之間的過渡值:0.4,0.6,0.7等)
- 3,系統內置估值器:IntEvaluator、FloatEvaluator、ArgbEvaluator(針對Color)
- 4,爲屬性動畫所特有,可自定義
八、Android Camera系統
重點相關概念及知識點:
$8.1、照相機物理架構(下圖來源於網絡)
爲生產者消費者模型:
Camera負責生產,Display負責消費
名詞解釋:
IPU: Image Process Unit 圖像處理單元,用於控制攝像機和顯示屏
DMA:內存映射(在這裏指將IPU採集到的數據DMA到內存裏面
QBUF(QueueBuffer):緩存隊列
DQBUF(DequeueBuffer):空閒隊列
$8.2、Camera Android架構(下圖來源於網絡)
$8.3、CameraService
$8.4、Camera、Camera2、CameraX
名稱 | 缺點 | 優點 |
---|---|---|
Camera | 1、要自己管理Camera實例; 2、處理與SurfaceView相關 |
開發者比較實現此開發流程 |
Camera2 | 接口更多了,使用更不方便 | 1、不用自己管理surfaceview; 2、基於狀態管理 |
CameraX | 目前還是alpha版 | 1、解決了設備兼容問題; 2、基於camera2封裝,調用更加簡單 |
$8.5、Surface、SurfaceView、SurfaceHolder
-
Surface: 對應一塊屏幕緩衝區,它是由SurfaceFlinger(屏幕顯示內容合成器)來管理的【原始緩衝區】的句柄(即Surface對象爲SurfaceFlinger所持有)。
每個Window對應一個Surface。所有的View都要畫在Surface的Canvas上。傳統的View共享一塊屏幕緩衝區,即共享一個Surface,且所有的繪製都在UI線程。- 總結:拿到Surface對象後,就可以獲取原始緩衝區中的原始數據或者往緩衝區中存儲數據、獲取Canvas畫布、其他。
-
SurfaceView:
它繼承自View,裏面新建了一個Window對像,因此SurfaceView內嵌了一個Surface,SurfaceView則用來控制Surface裏面的View的位置與尺寸。 -
SurfaceHolder:
接口,用於訪問和控制SurfaceView中Surface相關的方法。
Surface\SurfaceView\SurfaceHolder爲典型的MVC模式。
$8. 6、SurfaceTexture
SurfaceTexture和SurfaceView不同的是,它對圖像流的處理並不直接顯示,而是轉爲GL外部紋理,因此可用於圖像流數據的二次處理(如Camera濾鏡,桌面特效等)。比如Camera的預覽數據,變成紋理後有以下2種處理方式:
-
可以交給GLSurfaceView直接顯示,
-
也可以通過SurfaceTexture交給TextureView作爲View heirachy中的一個硬件加速層來顯示。
- 首先,SurfaceTexture從圖像流(來自Camera預覽,視頻解碼,GL繪製場景等)中獲得幀數據,當調用updateTexImage()時,
根據內容流中最近的圖像更新SurfaceTexture對應的GL紋理對象, - 接下來,就可以像操作普通GL紋理一樣操作它了。
- 首先,SurfaceTexture從圖像流(來自Camera預覽,視頻解碼,GL繪製場景等)中獲得幀數據,當調用updateTexImage()時,
-
TextureView與SurfaceView的區別:
- TextureView是將紋理加入到了View樹中,因此可以像操作普通View一樣操作此紋理控件。
- SurfaceView則是有獨立的Surface,可以在子線程中展示。獨立於View樹。
(下一篇將整理分享筆記:Android事件派發機制 、Handler消息機制以及Binder機制)