Android 性能優化四個方面總結

目錄

  • 一、四個方面
  • 二、卡頓優化
    • 1、Android系統顯示原理
    • 2、卡頓根本原因
    • 3、性能分析工具
      • (1)Profile GPU Rendering
      • (2)TraceView
      • (3)Systrace UI 性能分析
    • 4、優化建議
      • (1)布局優化
      • (2)避免過度繪制
      • (3)啟動優化
      • (4)合理的刷新機制
      • (5)其他
  • 三、內存優化
    • 1、Android內存管理機制
      • (1)Java對象生命周期
      • (2)內存分配
      • (3)內存回收機制
    • 2、內存分析工具
      • (1)Memory Monitor
      • (2)Heap Viewer
      • (3)Allocation Tracker
      • (4)Memory Analyzer Tool(MAT)
    • 3、常見內存泄漏場景
    • 4、優化內存空間
  • 四、穩定性優化
  • 五、耗電優化
  • 六、安裝包大小優化

一、四個方面

可以把用戶體驗的性能問題主要總結為4個類別:

  • 流暢

  • 穩定

  • 省電、省流量

  • 安裝包小

性能問題的主要原因是什么,原因有相同的,也有不同的,但歸根到底,不外乎內存使用、代碼效率、合適的策略邏輯、代碼質量、安裝包體積這一類問題,整理歸類如下:
在這里插入圖片描述
從圖中可以看到,打造一個高質量的應用應該以4個方向為目標:快、穩、省、小。

  • :使用時避免出現卡頓,響應速度快,減少用戶等待的時間,滿足用戶期望。

  • :減低 crash 率和 ANR 率,不要在用戶使用過程中崩潰和無響應。

  • :節省流量和耗電,減少用戶使用成本,避免使用時導致手機發燙。

  • :安裝包小可以降低用戶的安裝成本。

要想達到這4個目標,具體實現是在右邊框里的問題:卡頓、內存使用不合理、代碼質量差、代碼邏輯亂、安裝包過大,這些問題也是在開發過程中碰到最多的問題,在實現業務需求同時,也需要考慮到這點,多花時間去思考,如何避免功能完成后再來做優化,不然的話等功能實現后帶來的維護成本會增加。


二、卡頓優化

Android 應用啟動慢,使用時經常卡頓,是非常影響用戶體驗的,應該盡量避免出現。卡頓的場景有很多,按場景可以分為4類:UI 繪制、應用啟動、頁面跳轉、事件響應,如圖:
在這里插入圖片描述

這4種卡頓場景的根本原因可以分為兩大類:

  • 界面繪制:主要原因是繪制的層級深、頁面復雜、刷新不合理,由于這些原因導致卡頓的場景更多出現在UI和啟動后的初始界面以及跳轉到頁面的繪制上。

  • 數據處理:導致這種卡頓場景的原因是數據處理量太大,一般分為三種情況,一是數據在處理UI線程,二是數據處理占用CPU高,導致主線程拿不到時間片,三是內存增加導致GC頻繁,從而引起卡頓。

引起卡頓的原因很多,但不管怎么樣的原因和場景,最終都是通過設備屏幕上顯示來達到用戶,歸根到底就是顯示有問題,所以,要解決卡頓,就要先了解Android系統的顯示原理。


1、Android系統顯示原理

Android顯示過程可以簡單概括為:Android應用程序把經過測量、布局、繪制后的Surface緩存數據,通過SurfaceFlinger把數據渲染到顯示屏幕上, 通過Android的刷新機制來刷新數據。也就是說應用層負責繪制,系統層負責渲染,通過進程間通信把應用層需要繪制的數據傳遞到系統層服務,系統層服務通過刷新機制把數據更新到屏幕上

我們都知道在Android的每個View繪制中有三個核心步驟:Measure、Layout、Draw。具體實現是從 ViewRootImp類的performTraversals() 方法開始執行,Measure和Layout都是通過遞歸來獲取View的大小和位置,并且以深度作為優先級,可以看出 層級越深、元素越多、耗時也就越長

真正把需要顯示的數據渲染到屏幕上,是通過系統級進程中的SurfaceFlinger服務來實現的,那么這個SurfaceFlinger服務主要做了哪些工作呢?如下:

  • 響應客戶端事件,創建Layer與客戶端的Surface建立連接。

  • 接收客戶端數據及屬性,修改Layer屬性,如尺寸、顏色、透明度等。

  • 將創建的Layer內容刷新到屏幕上。

  • 維持Layer的序列,并對Layer最終輸出做出裁剪計算。

既然是兩個不同的進程,那么肯定是需要一個跨進程的通信機制來實現數據傳遞,在Android顯示系統中,使用了Android的匿名共享內存:SharedClient,每一個應用和SurfaceFlinger之間都會創建一個SharedClient ,然后在每個SharedClient中,最多可以創建31個 SharedBufferStack,每個Surface都對應一個SharedBufferStack,也就是一個Window。

一個SharedClient對應一個Android應用程序,而一個Android應用程序可能包含多個窗口,即Surface。也就是說SharedClient包含的是SharedBufferStack的集合,其中在顯示刷新機制中用到了雙緩沖和三重緩沖技術。最后總結起來顯示整體流程分為三個模塊:應用層繪制到緩存區,SurfaceFlinger把緩存區數據渲染到屏幕,由于是不同的進程,所以使用Android的匿名共享內存SharedClient緩存需要顯示的數據來達到目的。

除此之外,我們還需要一個名詞:FPS。FPS表示每秒傳遞的幀數在理想情況下,60FPS就感覺不到卡,這意味著每個繪制時長應該在16ms以內。但是 Android系統很有可能無法及時完成那些復雜的頁面渲染操作。Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需的60FPS。如果某個操作花費的時間是24ms ,系統在得到VSYNC信號時就無法正常進行正常渲染,這樣就發生了丟幀現象。那么用戶在32ms內看到的會是同一幀畫面,這種現象在執行動畫或滑動列表比較常見,還有可能是你的Layout太過復雜,層疊太多的繪制單元,無法在16ms完成渲染,最終引起刷新不及時。


2、卡頓根本原因

根據Android系統顯示原理可以看到,影響繪制的根本原因有以下兩個方面:

  • 繪制任務太重,繪制一幀內容耗時太長

  • 主線程太忙,根據系統傳遞過來的VSYNC信號來時還沒準備好數據導致丟幀

繪制耗時太長,有一些工具可以幫助我們定位問題。主線程太忙則需要注意了,主線程關鍵職責是處理用戶交互,在屏幕上繪制像素,并進行加載顯示相關的數據,所以特別需要避免任何主線程的事情,這樣應用程序才能保持對用戶操作的即時響應。總結起來,主線程主要做以下幾個方面工作:

  • UI生命周期控制

  • 系統事件處理

  • 消息處理

  • 界面布局

  • 界面繪制

  • 界面刷新

除此之外,應該盡量避免將其他處理放在主線程中,特別復雜的數據計算和網絡請求等。


3、性能分析工具

性能問題并不容易復現,也不好定位,但是真的碰到問題還是需要去解決的,那么分析問題和確認問題是否解決,就需要借助相應的的調試工具,比如查看Layout層次的Hierarchy View、Android系統上帶的GPU Profile工具和靜態代碼檢查工具Lint等,這些工具對性能優化起到非常重要的作用,所以要熟悉,知道在什么場景用什么工具來分析。


(1)Profile GPU Rendering

在手機開發者模式下,有一個卡頓檢測工具叫做:Profile GPU Rendering,如圖:
在這里插入圖片描述

它的功能特點如下:

  • 一個圖形監測工具,能實時反應當前繪制的耗時

  • 橫軸表示時間,縱軸表示每一幀的耗時

  • 隨著時間推移,從左到右的刷新呈現

  • 提供一個標準的耗時,如果高于標準耗時,就表示當前這一幀丟失


(2)TraceView

TraceView是Android SDK自帶的工具,用來分析函數調用過程,可以對Android的應用程序以及Framework層的代碼進行性能分析。它是一個圖形化的工具,最終會產生一個圖表,用于對性能分析進行說明,可以分析到每一個方法的執行時間,其中可以統計出該方法調用次數和遞歸次數,實際時長等參數維度,使用非常直觀,分析性能非常方便。


(3)Systrace UI 性能分析

Systrace是Android 4.1及以上版本提供的性能數據采樣和分析工具,它是通過系統的角度來返回一些信息。它可以幫助開發者收集Android關鍵子系統,如Surfaceflinger、WindowManagerService等Framework部分關鍵模塊、服務、View系統等運行信息,從而幫助開發者更直觀地分析系統瓶頸,改進性能。Systrace的功能包括跟蹤系統的I/O操作、內核工作隊列、CPU負載等,在UI顯示性能分析上提供很好的數據,特別是在動畫播放不流暢、渲染卡等問題上。


4、優化建議

  • 布局優化
  • 避免過度繪制
  • 啟動優化
  • 合理的刷新機制
  • 其他

(1)布局優化

布局是否合理主要影響的是頁面測量時間的多少,我們知道一個頁面的顯示測量和繪制過程都是通過遞歸來完成的,多叉樹遍歷的時間與樹的高度h有關,其時間復雜度O(h),如果層級太深,每增加一層則會增加更多的頁面顯示時間,所以布局的合理性就顯得很重要。

那布局優化有哪些方法呢,主要通過 減少層級、減少測量和繪制時間、提高復用性 三個方面入手。總結如下:

  • 減少層級:合理使用RelativeLayout和LinerLayout,合理使用Merge。

  • 提高顯示速度:使用ViewStub,它是一個看不見的、不占布局位置、占用資源非常小的視圖對象。

  • 布局復用:可以通過標簽(include)來提高復用。

  • 盡可能少用wrap_content:wrap_content 會增加布局measure時計算成本,在已知寬高為固定值時,不用wrap_content。

  • 其他:刪除控件中無用的屬性。


(2)避免過度繪制

過度繪制是指在屏幕上的某個像素在同一幀的時間內被繪制了多次。在多層次重疊的UI結構中,如果不可見的UI也在做繪制的操作,就會導致某些像素區域被繪制了多次,從而浪費了多余的CPU以及GPU源。

如何避免過度繪制呢,如下:

  • 布局上的優化:移除XML中非必須的背景,移除Window默認的背景、按需顯示占位背景圖片。

  • 自定義View優化:使用 canvas.clipRect()來幫助系統識別那些可見的區域,只有在這個區域內才會被繪制。


(3)啟動優化

通過對啟動速度的監控,發現影響啟動速度的問題所在,優化啟動邏輯,提高應用的啟動速度。啟動主要完成三件事:UI布局、繪制和數據準備。因此啟動速度優化就是需要優化這三個過程:

  • UI布局:應用一般都有閃屏頁,優化閃屏頁的UI布局,可以通過Profile GPU Rendering檢測丟幀情況。

  • 啟動加載邏輯優化:可以采用分布加載、異步加載、延期加載策略來提高應用啟動速度。

  • 數據準備:數據初始化分析,加載數據可以考慮用線程初始化等策略。


(4)合理的刷新機制

在應用開發過程中,因為數據的變化,需要刷新頁面來展示新的數據,但頻繁刷新會增加資源開銷,并且可能導致卡頓發生,因此,需要一個合理的刷新機制來提高整體的UI流暢度。合理的刷新需要注意以下幾點:

  • 盡量減少刷新次數

  • 盡量避免后臺有高的CPU線程運行

  • 縮小刷新區域


(5)其他

在實現動畫效果時,需要根據不同場景選擇合適的動畫框架來實現。有些情況下,可以用硬件加速方式來提供流暢度。


三、內存優化

在Android系統中有個垃圾內存回收機制,在虛擬機層自動分配和釋放內存,因此不需要在代碼中分配和釋放某一塊內存,從應用層面上不容易出現內存泄漏和內存溢出等問題,但是需要內存管理。Android系統在內存管理上有一個Generational Heap Memory模型,內存回收的大部分壓力不需要應用層關心,Generational Heap Memory有自己一套管理機制,當內存達到一個閾值時,系統會根據不同的規則自動釋放系統認為可以釋放的內存,也正是因為Android程序把內存控制的權力交給了Generational Heap Memory,一旦出現內存泄漏和溢出方面的問題,排查錯誤將會成為一項異常艱難的工作。除此之外,部分Android應用開發人員在開發過程中并沒有特別關注內存的合理使用,也沒有在內存方面做太多的優化,當應用程序同時運行越來越多的任務,加上越來越復雜的業務需求時,完全依賴Android的內存管理機制就會導致一系列性能問題逐漸呈現,對應用的穩定性和性能帶來不可忽視的影響,因此,解決內存問題和合理優化內存是非常有必要的。


1、Android內存管理機制

Android應用都是在 Android的虛擬機上運行,應用 程序的內存分配與垃圾回收都是由虛擬機完成的。在Android系統,虛擬機有兩種運行模式:Dalvik和ART。

(1)Java對象生命周期

在這里插入圖片描述
一般Java對象在虛擬機上有7個運行階段:

創建階段->應用階段->不可見階段->不可達階段->收集階段->終結階段->對象空間重新分配階段


(2)內存分配

在Android系統中,內存分配實際上是對堆的分配和釋放。當一個Android程序啟動,應用進程都是從一個叫做Zygote的進程衍生出來,系統啟動 Zygote 進程后,為了啟動一個新的應用程序進程,系統會衍生Zygote進程生成一個新的進程,然后在新的進程中加載并運行應用程序的代碼。其中,大多數的RAM pages被用來分配給Framework代碼,同時促使RAM資源能夠在應用所有進程之間共享。

但是為了整個系統的內存控制需要,Android系統會為每一個應用程序都設置一個硬性的Dalvik Heap Size最大限制閾值,整個閾值在不同設備上會因為RAM大小不同而有所差異。如果應用占用內存空間已經接近整個閾值時,再嘗試分配內存的話,就很容易引起內存溢出的錯誤。


(3)內存回收機制

我們需要知道的是,在Java中內存被分為三個區域:Young Generation(新生代)、Old Generation(年老代)、Permanent Generation(持久代)。最近分配的對象會存放在Young Generation區域。對象在某個時機觸發GC回收垃圾,而沒有回收的就根據不同規則,有可能被移動到Old Generation,最后累積一定時間在移動到Permanent Generation 區域。系統會根據內存中不同的內存數據類型分別執行不同的GC操作。GC通過確定對象是否被活動對象引用來確定是否收集對象,進而動態回收無任何引用的對象占據的內存空間。但需要注意的是頻繁的GC會增加應用的卡頓情況,影響應用的流暢性,因此需要盡量減少系統GC行為,以便提高應用的流暢度,減小卡頓發生的概率。


2、內存分析工具

做內存優化前,需要了解當前應用的內存使用現狀,通過現狀去分析哪些數據類型有問題,各種類型的分布情況如何,以及在發現問題后如何發現是哪些具體對象導致的,這就需要相關工具來幫助我們。


(1)Memory Monitor

Memory Monitor是一款使用非常簡單的圖形化工具,可以很好地監控系統或應用的內存使用情況,主要有以下功能:

  • 顯示可用和已用內存,并且以時間為維度實時反應內存分配和回收情況。

  • 快速判斷應用程序的運行緩慢是否由于過度的內存回收導致。

  • 快速判斷應用是否由于內存不足導致程序崩潰。


(2)Heap Viewer

Heap Viewer的主要功能是查看不同數據類型在內存中的使用情況,可以看到當前進程中的Heap Size的情況,分別有哪些類型的數據,以及各種類型數據占比情況。通過分析這些數據來找到大的內存對象,再進一步分析這些大對象,進而通過優化減少內存開銷,也可以通過數據的變化發現內存泄漏。


(3)Allocation Tracker

Memory Monitor和Heap Viewer都可以很直觀且實時地監控內存使用情況,還能發現內存問題,但發現內存問題后不能再進一步找到原因,或者發現一塊異常內存,但不能區別是否正常,同時在發現問題后,也不能定位到具體的類和方法。這時就需要使用另一個內存分析工具Allocation Tracker,進行更詳細的分析,Allocation Tracker可以分配跟蹤記錄應用程序的內存分配,并列出了它們的調用堆棧,可以查看所有對象內存分配的周期。


(4)Memory Analyzer Tool(MAT)

MAT是一個快速,功能豐富的Java Heap分析工具,通過分析Java進程的內存快照HPROF分析,從眾多的對象中分析,快速計算出在內存中對象占用的大小,查看哪些對象不能被垃圾收集器回收,并可以通過視圖直觀地查看可能造成這種結果的對象。


3、常見內存泄漏場景

如果在內存泄漏發生后再去找原因并修復會增加開發的成本,最好在編寫代碼時就能夠很好地考慮內存問題,寫出更高質量的代碼,這里列出一些常見的內存泄漏場景,在以后的開發過程中需要避免這類問題。

  • 資源性對象未關閉:比如Cursor、File文件等,往往都用了一些緩沖,在不使用時,應該及時關閉它們。

  • 注冊對象未注銷:比如事件注冊后未注銷,會導致觀察者列表中維持著對象的引用。

  • 類的靜態變量持有大數據對象

  • 非靜態內部類的靜態實例

  • Handler臨時性內存泄漏:如果Handler是非靜態的,容易導致Activity或Service不會被回收。

  • 容器中的對象沒清理造成的內存泄漏

  • WebView:WebView存在著內存泄漏的問題,在應用中只要使用一次WebView,內存就不會被釋放掉。

除此之外,內存泄漏可監控,常見的就是用LeakCanary第三方庫,這是一個檢測內存泄漏的開源庫,使用非常簡單,可以在發生內存泄漏時告警,并且生成leak tarce分析泄漏位置,同時可以提供Dump文件進行分析。


4、優化內存空間

沒有內存泄漏,并不意味著內存就不需要優化,在移動設備上,由于物理設備的存儲空間有限,Android 系統對每個應用進程也都分配了有限的堆內存,因此使用最小內存對象或者資源可以減小內存開銷,同時讓GC 能更高效地回收不再需要使用的對象,讓應用堆內存保持充足的可用內存,使應用更穩定高效地運行。常見做法如下:

  • 對象引用:強引用、軟引用、弱引用、虛引用四種引用類型,根據業務需求合理使用不同,選擇不同的引用類型。

  • 減少不必要的內存開銷:注意自動裝箱,增加內存復用,比如有效利用系統自帶的資源、視圖復用、對象池、Bitmap對象的復用。

  • 使用最優的數據類型:比如針對數據類容器結構,可以使用ArrayMap數據結構,避免使用枚舉類型,使用緩存Lrucache等等。

  • 圖片內存優化:可以設置位圖規格,根據采樣因子做壓縮,用一些圖片緩存方式對圖片進行管理等等。


四、穩定性優化

Android應用的穩定性定義很寬泛,影響穩定性的原因很多,比如內存使用不合理、代碼異常場景考慮不周全、代碼邏輯不合理等,都會對應用的穩定性造成影響。其中最常見的兩個場景是:Crash和ANR,這兩個錯誤將會使得程序無法使用,比較常用的解決方式如下:

  • 提高代碼質量:比如開發期間的代碼審核,看些代碼設計邏輯,業務合理性等。

  • 代碼靜態掃描工具:常見工具有Android Lint、Findbugs、Checkstyle、PMD等等。

  • Crash監控:把一些崩潰的信息,異常信息及時地記錄下來,以便后續分析解決。

  • Crash上傳機制:在Crash后,盡量先保存日志到本地,然后等下一次網絡正常時再上傳日志信息。


五、耗電優化

在移動設備中,電池的重要性不言而喻,沒有電什么都干不成。對于操作系統和設備開發商來說,耗電優化一致沒有停止,去追求更長的待機時間,而對于一款應用來說,并不是可以忽略電量使用問題,特別是那些被歸為“電池殺手”的應用,最終的結果是被卸載。因此,應用開發者在實現需求的同時,需要盡量減少電量的消耗。

在Android5.0以前,在應用中測試電量消耗比較麻煩,也不準確,5.0之后專門引入了一個獲取設備上電量消耗信息的API:Battery Historian。Battery Historian是一款由Google提供的Android系統電量分析工具,和Systrace一樣,是一款圖形化數據分析工具,直觀地展示出手機的電量消耗過程,通過輸入電量分析文件,顯示消耗情況,最后提供一些可供參考電量優化的方法。

除此之外,還有一些常用方案可提供:

  • 計算優化,避開浮點運算等

  • 避免WaleLock使用不當

  • 使用Job Scheduler


六、安裝包大小優化

應用安裝包大小對應用使用沒有影響,但應用的安裝包越大,用戶下載的門檻越高,特別是在移動網絡情況下,用戶在下載應用時,對安裝包大小的要求更高,因此,減小安裝包大小可以讓更多用戶愿意下載和體驗產品。

常用應用安裝包的構成,如圖所示:
在這里插入圖片描述

從圖中我們可以看到:

  • assets文件夾:存放一些配置文件、資源文件,assets不會自動生成對應的 ID,而是通過AssetManager類的接口獲取。

  • res:res是resource的縮寫,這個目錄存放資源文件,會自動生成對應的ID并映射到 .R文件中,訪問直接使用資源ID。

  • META-INF:保存應用的簽名信息,簽名信息可以驗證APK文件的完整性。

  • AndroidManifest.xml:這個文件用來描述Android應用的配置信息,一些組件的注冊信息、可使用權限等。

  • classes.dex:Dalvik字節碼程序,讓Dalvik虛擬機可執行,一般情況下,Android應用在打包時通過Android SDK中的dx工具將Java字節碼轉換為Dalvik字節碼。

  • resources.arsc:記錄著資源文件和資源ID之間的映射關系,用來根據資源ID尋找資源。

減少安裝包大小的常用方案:

  • 代碼混淆:使用ProGuard代碼混淆器工具,它包括壓縮、優化、混淆等功能。

  • 資源優化:比如使用Android Lint刪除冗余資源,資源文件最少化等。

  • 圖片優化:比如利用AAPT工具對PNG格式的圖片做壓縮處理,降低圖片色彩位數等。

  • 避免重復功能的庫,使用WebP圖片格式

  • 插件化:比如功能模塊放在服務器上,按需下載,可以減少安裝包大小。

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

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

相關文章

pycharm/clion/idea等產品多含代碼左移右移操作

左移 選中多行代碼后,按下Tab鍵,一次縮進四個字符 右移 鼠標選中多行代碼后,同時按住shiftTab鍵,一次左移四個字符

Android 開源框架選擇

目錄一、前言二、APP的整體架構三、技術選型的考量點四、日志記錄能力五、JSON解析能力1、gson2、jackson3、Fastjson4、LoganSquare六、數據庫操作能力1、ActiveAndroid2、ormlite3、greenDAO4、Realm七、網絡通信能力1、android-async-http2、OkHttp3、Volley4、Retrofit八、…

使用opensll的md5對于string進行加密

代碼 #include <openssl/md5.h>#include <sstream> #include <iomanip> #include <iostream>void get_string_md5(const std::string& await_md5_string) {unsigned char md5[MD5_DIGEST_LENGTH];MD5(reinterpret_cast<unsigned const char*&g…

Android Studio 自定義Gradle Plugin

一、簡介 之前公司的一個項目需要用到Gradle插件來修改編譯后的class文件&#xff0c;今天有時間就拿出來整理一下&#xff0c;學習一下Gradle插件的編寫還是一件十分有意義的事。 二、Gradle插件類型 一種是直接在項目中的gradle文件里編寫&#xff0c;這種方式的缺點是無法復…

C++創建臨時文件

命令 std::string original_backup_file std::tmpnam(nullptr);

Android Studio Gradle兩種更新方式

第一種、Android Studio自動更新 第一步&#xff1a;修改gradle版本 修改項目根目錄/gradle/wrapper/gradle-wrapper.properties最后一行的地址&#xff1a; distributionUrlhttps://services.gradle.org/distributions/gradle-3.3-all.zip新gradle地址從官方下載的地方有。…

C++使用openssl實現aes加解密,其中加密是string到文件,解密是文件到string,切合項目背景

代碼 使用md5對于用戶輸入的密碼進行保護,也使得密碼的長度固定crypto_util.h#pragma once#include <string>namespace hsm{ namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]);void aes_encrypt_to_file(const std::string &fi…

Android Canvas的drawText()和文字居中方案

自定義View是繪制文本有三類方法&#xff1a; // 第一類 public void drawText (String text, float x, float y, Paint paint) public void drawText (String text, int start, int end, float x, float y, Paint paint) public void drawText (CharSequence text, int start…

IntelliJ IDEA配置Tomcat

查找該問題的童鞋我相信IntelliJ IDEA&#xff0c;Tomcat的下載&#xff0c;JDK等其他的配置都應該完成了&#xff0c;那我直接進入正題了。 1、新建一個項目 2、由于這里我們僅僅為了展示如何成功部署Tomcat&#xff0c;以及配置完成后成功運行一個jsp文件&#xff0c;我僅勾…

C++對于文件的相關操作 創建、讀寫、刪除代碼

創建 /*** brief 創建文件:在密碼設備內部創建用于存儲用戶數據的文件* param pucFileName 緩沖區指針&#xff0c;用于存放輸入的文件名&#xff0c;最大長度128字節* param uiNameLen 文件名長度* param uiFileSize 文件所占存儲空間的長度*/void CreateFile(sdf_uint8_t…

Android開發之Path詳解

目錄一、xxxTo方法1、lineTo(float x, float y)2、moveTo(float x, float y)3、arcTo3.1、arcTo(RectF oval, float startAngle, float sweepAngle)3.2、arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)3.3、arcTo(float left, float top, float r…

git大文件拷貝代碼命令

git clone 鏈接 --recursive

Android APK打包流程

目錄一、概述二、打包流程1、打包資源文件&#xff0c;生成R.java文件2、處理aidl文件&#xff0c;生成相應的Java文件3、編譯項目源代碼&#xff0c;生成class文件4、轉換所有的class文件&#xff0c;生成classes.dex文件5、打包生成APK文件6、對APK文件進行簽名7、對簽名后的…

使用openssl,實現輸入和輸出都是字符串的類型,注意:輸入最好是16的倍數

頭文件crypto_util.h #pragma once#include <string>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]);std::string aes_encrypt_to_string(const std::string &string,const std::string &password);std::s…

Android Studio 安裝ASM插件

目錄一、安裝步驟1、Android Studio -> Preferences...2、Plugins -> Browse repositories...3、搜索ASM -> 選中要安裝的插件 -> 右側點擊Install4、安裝完后點擊Restart Android Studio5、Android Studio重啟后右側會有個ASM圖標6、找一個類右鍵 -> Show Byte…

使用openssl完成aes-cbc模式的數據加解密,輸入和輸出都是字符串的形式

代碼 #include <cstring> #include <memory>#include <openssl/aes.h> #include <openssl/md5.h>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]){MD5_CTX md5_ctx{};MD5_Init(&md5_ctx);MD5…

Android 網絡異常

目錄前言一、UnknownHostException1、網絡斷開驗證2、DNS 服務器意外掛掉驗證3、DNS 服務器故障驗證4、所需診斷信息二、ConnectTimeoutException三、SocketTimeoutException1、子錯誤 - 讀超時2、子錯誤 - SSL 握手超時3、子錯誤 - 未知原因四、HttpHostConnectException1、服…

Android ViewRoot、DecorViewWindow淺析

目錄簡介目錄1、VeiwRoot1.1、簡介1.2、特別注意2、DecorView2.1、定義2.2、作用2.3、特別說明3、Window4、Activity5、之間關系5.1、總結5.2、之間的關系簡介 DecorView為整個Window界面的最頂層View。DecorView只有一個子元素為LinearLayout。代表整個Window界面&#xff0c;…

Java集合Stream類

Java集合Stream類 ----按條件對集合進行過濾filter public class Test {public static void main(String[] args) {List<String>allnew ArrayList<>();all.add("ghjt");all.add("ghjiiii");Stream<String>streamall.stream();List<S…

使用openssl完成aes-ecb模式的數據加解密,輸入和輸出都是字符串類型

代碼 #include <cstring> #include <memory>#include <openssl/aes.h> #include <openssl/md5.h>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]){MD5_CTX md5_ctx{};MD5_Init(&md5_ctx);MD5…