終于有人把安卓程序員必學知識點全整理出來了,送大廠面經一份!

除了Bug,最讓你頭疼的問題是什么?單身?禿頭?996?面試造火箭,工作擰螺絲?

作為安卓開發者,除了Bug,經常會碰到下面這些問題:

應用卡頓,丟幀,屏幕畫面撕裂,操作界面刷新緩慢,UI不美觀,布局混亂…這些問題頻發的話,年后可能就不用來了。

開發App的時候,你是否會覺得界面卡頓?尤其是自定義View的時候。

Android 應用的卡頓、丟幀等,這些影響用戶體驗的因素絕大部分都與 16ms 這個值有關。Android 設備的刷新率也是 60Hz,Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染,如果超過了16ms,我們則認為發生了卡頓。

二、顯示系統基礎知識

在一個典型的顯示系統中,一般包括CPU、GPU、Display三個部分, CPU負責計算幀數據,把計算好的數據交給GPU,GPU會對圖形數據進行渲染,渲染好后放到buffer(圖像緩沖區)里存起來,然后Display(屏幕或顯示器)負責把buffer里的數據呈現到屏幕上。如下圖:

2.1 基礎概念

  • 屏幕刷新頻率 一秒內屏幕刷新的次數(一秒內顯示了多少幀的圖像),單位 Hz(赫茲),如常見的 60 Hz。刷新頻率取決于硬件的固定參數(不會變的)。

  • 逐行掃描 顯示器并不是一次性將畫面顯示到屏幕上,而是從左到右邊,從上到下逐行掃描,順序顯示整屏的一個個像素點,不過這一過程快到人眼無法察覺到變化。以 60 Hz 刷新率的屏幕為例,這一過程即 1000 / 60 ≈ 16ms。

  • 幀率 (Frame Rate) 表示 GPU 在一秒內繪制操作的幀數,單位 fps。例如在電影界采用 24 幀的速度足夠使畫面運行的非常流暢。而 Android 系統則采用更加流程的 60 fps,即每秒鐘GPU最多繪制 60 幀畫面。幀率是動態變化的,例如當畫面靜止時,GPU 是沒有繪制操作的,屏幕刷新的還是buffer中的數據,即GPU最后操作的幀數據。

  • 畫面撕裂(tearing) 一個屏幕內的數據來自2個不同的幀,畫面會出現撕裂感,如下圖

明顯看出畫面錯位的位置,這就是畫面撕裂。

2.2 雙緩存

2.2.1 畫面撕裂 原因

屏幕刷新頻是固定的,比如每16.6ms從buffer取數據顯示完一幀,理想情況下幀率和刷新頻率保持一致,即每繪制完成一幀,顯示器顯示一幀。但是CPU/GPU寫數據是不可控的,所以會出現buffer里有些數據根本沒顯示出來就被重寫了,即buffer里的數據可能是來自不同的幀的, 當屏幕刷新時,此時它并不知道buffer的狀態,因此從buffer抓取的幀并不是完整的一幀畫面,即出現畫面撕裂。

簡單說就是Display在顯示的過程中,buffer內數據被CPU/GPU修改,導致畫面撕裂。

2.2.2 雙緩存

那咋解決畫面撕裂呢? 答案是使用 雙緩存。

由于圖像繪制和屏幕讀取 使用的是同個buffer,所以屏幕刷新時可能讀取到的是不完整的一幀畫面。

雙緩存,讓繪制和顯示器擁有各自的buffer:GPU 始終將完成的一幀圖像數據寫入到 Back Buffer,而顯示器使用 Frame Buffer,當屏幕刷新時,Frame Buffer 并不會發生變化,當Back buffer準備就緒后,它們才進行交換。如下圖:

2.2.3 VSync

問題又來了:什么時候進行兩個buffer的交換呢?

假如是 Back buffer準備完成一幀數據以后就進行,那么如果此時屏幕還沒有完整顯示上一幀內容的話,肯定是會出問題的。看來只能是等到屏幕處理完一幀數據后,才可以執行這一操作了。

當掃描完一個屏幕后,設備需要重新回到第一行以進入下一次的循環,此時有一段時間空隙,稱為VerticalBlanking Interval(VBI)。那,這個時間點就是我們進行緩沖區交換的最佳時間。因為此時屏幕沒有在刷新,也就避免了交換過程中出現 screen tearing的狀況。

VSync(垂直同步)是VerticalSynchronization的簡寫,它利用VBI時期出現的vertical sync pulse(垂直同步脈沖)來保證雙緩沖在最佳時間點才進行交換。另外,交換是指各自的內存地址,可以認為該操作是瞬間完成。

所以說V-sync這個概念并不是Google首創的,它在早年的PC機領域就已經出現了。

三、Android屏幕刷新機制

3.1 Android4.1之前的問題

具體到Android中,在Android4.1之前,屏幕刷新也遵循 上面介紹的 雙緩存+VSync 機制。如下圖:

以時間的順序來看下將會發生的過程:

  1. Display顯示第0幀數據,此時CPU和GPU渲染第1幀畫面,且在Display顯示下一幀前完成
  2. 因為渲染及時,Display在第0幀顯示完成后,也就是第1個VSync后,緩存進行交換,然后正常顯示第1幀
  3. 接著第2幀開始處理,是直到第2個VSync快來前才開始處理的。
  4. 第2個VSync來時,由于第2幀數據還沒有準備就緒,緩存沒有交換,顯示的還是第1幀。這種情況被Android開發組命名為“Jank”,即發生了丟幀
  5. 當第2幀數據準備完成后,它并不會馬上被顯示,而是要等待下一個VSync 進行緩存交換再顯示。

所以總的來說,就是屏幕平白無故地多顯示了一次第1幀。

原因是 第2幀的CPU/GPU計算 沒能在VSync信號到來前完成 。

我們知道,雙緩存的交換 是在Vsyn到來時進行,交換后屏幕會取Frame buffer內的新數據,而實際 此時的Back buffer 就可以供GPU準備下一幀數據了。 如果 Vsyn到來時 CPU/GPU就開始操作的話,是有完整的16.6ms的,這樣應該會基本避免jank的出現了(除非CPU/GPU計算超過了16.6ms)。 那如何讓 CPU/GPU計算在 Vsyn到來時進行呢?

3.2 drawing with VSync

為了優化顯示性能,Google在Android 4.1系統中對Android Display系統進行了重構,實現了Project Butter(黃油工程):系統在收到VSync pulse后,將馬上開始下一幀的渲染。即一旦收到VSync通知(16ms觸發一次),CPU和GPU 才立刻開始計算然后把數據寫入buffer。如下圖:

CPU/GPU根據VSYNC信號同步處理數據,可以讓CPU/GPU有完整的16ms時間來處理數據,減少了jank。

一句話總結,VSync同步使得CPU/GPU充分利用了16.6ms時間,減少jank。

問題又來了,如果界面比較復雜,CPU/GPU的處理時間較長 超過了16.6ms呢?如下圖:

  1. 在第二個時間段內,但卻因 GPU 還在處理 B 幀,緩存沒能交換,導致 A 幀被重復顯示。
  2. 而B完成后,又因為缺乏VSync pulse信號,它只能等待下一個signal的來臨。于是在這一過程中,有一大段時間是被浪費的。
  3. 當下一個VSync出現時,CPU/GPU馬上執行操作(A幀),且緩存交換,相應的顯示屏對應的就是B。這時看起來就是正常的。只不過由于執行時間仍然超過16ms,導致下一次應該執行的緩沖區交換又被推遲了——如此循環反復,便出現了越來越多的“Jank”。

為什么 CPU 不能在第二個 16ms 處理繪制工作呢?

原因是只有兩個 buffer,Back buffer正在被GPU用來處理B幀的數據, Frame buffer的內容用于Display的顯示,這樣兩個buffer都被占用,CPU 則無法準備下一幀的數據。 那么,如果再提供一個buffer,CPU、GPU 和顯示設備都能使用各自的buffer工作,互不影響。

3.3 三緩存

三緩存就是在雙緩沖機制基礎上增加了一個 Graphic Buffer 緩沖區,這樣可以最大限度的利用空閑時間,帶來的壞處是多使用的一個 Graphic Buffer 所占用的內存。

  1. 第一個Jank,是不可避免的。但是在第二個 16ms 時間段,CPU/GPU 使用 第三個 Buffer 完成C幀的計算,雖然還是會多顯示一次 A 幀,但后續顯示就比較順暢了,有效避免 Jank 的進一步加劇。

  2. 注意在第3段中,A幀的計算已完成,但是在第4個vsync來的時候才顯示,如果是雙緩沖,那在第三個vynsc就可以顯示了。

三緩沖有效利用了等待vysnc的時間,減少了jank,但是帶來了延遲。 所以,是不是 Buffer 越多越好呢?這個是否定的,Buffer 正常還是兩個,當出現 Jank 后三個足以。

以上就是Android屏幕刷新的原理了。

小結

有了這么多優秀的開發工具,可以做出更高質量的Android應用。

當然了,“打鐵還需自身硬”,想要寫出優秀的代碼,最重要的一點還是自身的技術水平,不然用再好的工具也不能發揮出它的全部實力。

在這里我也分享一份大佬自己收錄整理的Android學習PDF+架構視頻+面試文檔+源碼筆記,還有高級架構技術進階腦圖、Android開發面試專題資料,高級進階架構資料這些都是我閑暇還會反復翻閱的精品資料。在腦圖中,每個知識點專題都配有相對應的實戰項目,可以有效的幫助大家掌握知識點。

總之也是在這里幫助大家學習提升進階,也節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習

oid開發面試專題資料,高級進階架構資料**這些都是我閑暇還會反復翻閱的精品資料。在腦圖中,每個知識點專題都配有相對應的實戰項目,可以有效的幫助大家掌握知識點。

總之也是在這里幫助大家學習提升進階,也節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習

如果你有需要的話,可以點擊這里領取

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/386524.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/386524.shtml
英文地址,請注明出處:http://en.pswp.cn/news/386524.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ABA問題

CAS:對于內存中的某一個值V,提供一個舊值A和一個新值B。如果提供的舊值V和A相等就把B寫入V。這個過程是原子性的。 CAS執行結果要么成功要么失敗,對于失敗的情形下一班采用不斷重試。或者放棄。 ABA:如果另一個線程修改V值假設原…

mq引入以后的缺點

系統可用性降低? 一旦mq不能使用以后,系統A不能發送消息到mq,系統BCD無法從mq中獲取到消息.整個系統就崩潰了. 如何解決: 系統復雜程度增加? 加入mq以后,mq引入來的問題很多,然后導致系統的復雜程度增加. 如何解決 系統的一致性降低? 有人給系統A發送了一個請求,本來這個請求…

網易云的朋友給我這份339頁的Android面經,成功入職阿里

IT行業的前景 近幾年來,大數據、人工智能AI、物聯網等一些技術不斷發展,也讓人們看到了IT行業的繁榮與良好的前景。越來越多的高校學府加大了對計算機的投入,設立相應的熱門專業來吸引招生。當然也有越來越多的人選擇從事這個行業&#xff0…

AQS相關邏輯解析

關心QPS TPS 如何讓線程停留在lock 1、競爭鎖-(拿到鎖的線程、沒拿到鎖的線程) 臨界區的資源(static redis 數據庫變量 配置中心config zookeeper)大家共享都可以獲得的資源 臨界區沒拿到鎖的未拿到鎖線程進行停留 2、怎么讓線程停留在Lock方法里 …

git介紹和常用操作

轉載于:https://www.cnblogs.com/kesz/p/11124423.html

網易云的朋友給我這份339頁的Android面經,滿滿干貨指導

想要成為一名優秀的Android開發,你需要一份完備的知識體系,在這里,讓我們一起成長為自己所想的那樣~。 25%的面試官會在頭5分鐘內決定面試的結果60%的面試官會在頭15分鐘內決定面試的結果 一般來說,一場單面的時間在30分鐘左右&…

synchronized 和Lock區別

synchronized實現原理 Java中每一個對象都可以作為鎖,這是synchronized實現同步的基礎: 普通同步方法,鎖是當前實例對象靜態同步方法,鎖是當前類的class對象同步方法塊,鎖是括號里面的對象 當一個線程訪問同步代碼塊…

美團安卓面試,難道Android真的涼了?快來收藏!

我所接觸的Android開發者,百分之九十五以上 都遇到了以下幾點致命弱點! 如果這些問題也是阻止你升職加薪,跳槽大廠的阻礙。 那么我確信可以幫你突破瓶頸! 1.開發者的門越來越高: 小廠的機會少了,大廠…

django -- 實現ORM登錄

前戲 上篇文章寫了一個簡單的登錄頁面,那我們可不可以實現一個簡單的登錄功能呢?如果登錄成功,給返回一個頁面,失敗給出錯誤的提示呢? 在之前學HTML的時候,我們知道,網頁在往服務器提交數據的時…

美團點評APP在移動網絡性能優化的實踐,通用流行框架大全

" 對于程序員來說,如果哪一天開始他停止了學習,那么他的職業生涯便開始宣告消亡。” 高薪的IT行業是眾多年輕人的職業夢想,然而,一旦身入其中卻發覺沒有想像中那么美好。被稱為IT藍領的編程員,工作強度大&#xf…

java 8大happen-before原則超全面詳解

再來重復下八大原則: 單線程happen-before原則:在同一個線程中,書寫在前面的操作happen-before后面的操作。鎖的happen-before原則:同一個鎖的unlock操作happen-before此鎖的lock操作。volatile的happen-before原則:對…

centos7.0利用yum快速安裝mysql8.0

我這里直接使用MySQL Yum存儲庫的方式快速安裝: 抽象 MySQL Yum存儲庫提供用于在Linux平臺上安裝MySQL服務器,客戶端和其他組件的RPM包。這些軟件包還可以升級和替換從Linux發行版本機軟件存儲庫安裝的任何第三方MySQL軟件包,如果可以從MySQL…

騰訊3輪面試都問了Android事件分發,論程序員成長的正確姿勢

前言 這些題目是網友去美團等一線互聯網公司面試被問到的題目。筆者從自身面試經歷、各大網絡社交技術平臺搜集整理而成,熟悉本文中列出的知識點會大大增加通過前兩輪技術面試的幾率。 主要分為以下幾部分: (1)Android面試題 …

happens-before規則和as-if-serial語義

概述 本文大部分整理自《Java并發編程的藝術》,溫故而知新,加深對基礎的理解程度。 指令序列的重排序 我們在編寫代碼的時候,通常自上而下編寫,那么希望執行的順序,理論上也是逐步串行執行,但是為了提高…

安裝nodejs

1.安裝nodejs:node-v8.12.0-x64.msi; 2.檢測是否安裝成功: 3.地址欄打開命令行:輸入 cmd回車 4.檢測node是否安裝成功:node -v 看到版本號就是安裝成功了 5.檢測npm是否成功:npm -v 是安裝成功了 6、如果npm成功了,把 package.js…

貼片晶振無源石英諧振器直插晶振

貼片晶振 貼片晶振3.579M~25MHz無源石英諧振器直插晶振 文章目錄 貼片晶振前言一、貼片晶振3.579M~25MHz無源石英諧振器直插晶振二、屬性三、技術參數總結前言 貼片晶振(Surface Mount Crystal Oscillator)是一種采用表面貼裝技術進行安裝的晶振。它的主要特點是封裝小巧、安…

這些新技術你們都知道嗎?成功收獲美團,小米安卓offer

前言 近期被兩則消息刷屏,【字節跳動持續大規模招聘,全年校招超過1萬人】【騰訊有史以來最大規模的校招啟動】當然Android崗位也包含在內,因此Android還是有很多機會的。結合往期面試的同學(主要是校招)經驗&#xff…

CompareAndSwap原子操作原理

在翻閱AQS(AbstractQueuedSynchronizer)類的過程中,發現其進行原子操作的時候采用的是CAS。涉及的代碼如下: 1: private static final Unsafe unsafe Unsafe.getUnsafe(); 2: private static final long stateOffset; 3: private static f…

STemWin移植筆記

實現將STemWin圖形庫移植到STM32F103ZET中,記錄簡單的操作步驟,以便自己后續查閱。 1/ 從官網獲取STemWin庫的壓縮包en.stemwin.zip。 2/ 解壓后,在路徑STemWin_Library_V1.2.0\Libraries\STemWinLibrary532下可以找到庫文件。 3/ 移植前的準…

這些新技術你們都知道嗎?看這一篇就夠了!

前言 現在已經進入招聘季節,本篇文章旨在分享知名互聯網企業面試官面試方法和心得,希望通過本文的閱讀能給程序員帶來不一樣的面試體驗和感受,放松面試心態,積極備戰! 面試題 PS:由于文章篇幅問題&#x…