日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

App性能优化浅谈

發布時間:2023/12/14 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 App性能优化浅谈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

前段時間給公司的小伙伴們進行了關于app性能優化的技術分享,這里我稍微整理一下也給大家分享一下,關于性能優化這個話題很大,涉及面可以很廣,也可以很深入,本人能力有限,不會給大家講特別難懂,特別底層的東西,都是我們開發能著手去做的點,大家都在講性能優化,但對于項目經驗不夠豐富的朋友很難有一個概念,做優化的時候也會比較茫然,這里我就給大家指明方向。

從何講起?

筆者在做產品開發的時候,也遇到性能瓶頸,測試工程師反饋了一些比較明顯的問題,比如UI界面的過度繪制,列表滑動有明顯卡頓,比較耗內存等等,但以往的都沒有針對性的去做相應的優化,所以借著保證產品質量的出發點,自己定了相關的性能優化方案,可能不太成熟,不過可以逐步完善,并找到最適合自己產品的優化方案。

這里我定了四個方向:
- 響應時間(Response Time)
- 界面卡頓(ANR)
- 耗內存(Memory)
- 內存泄露(Out of memory)

響應時間

這里指的是客戶端與服務端交互,拿到數據、解析、再到顯示到界面整個過程耗費的時間。

這個部分涉及客戶端的優化,也涉及服務端的優化,這里只討論客戶端。

HTTP請求方式

我們的app一般離不開網絡,請求接口是最平常的操作了,如何請求,請求什么我們在開發初期就要定好,服務端給我的提供的接口,大致可以通過GET、POST、HEAD、PUT、DELETE這幾種請求方式,不同的請求方式有不同應用場景,比如GET請求,應當用來請求返回結果,參數是作為url的一部分;POST請求,用于請求會更改服務端數據或狀態;HEAD請求跟GET一樣,只是服務器不能在響應里返回消息主體;PUT請求,用于將網頁放置正確的地方;DELETE請求用于刪除服務器指定文檔。

使用優秀的開源Http框架是我們比較好的選擇,它的優點是經過市場的驗證,很多坑都被填過,缺點也是我們需要去深究它才能對其進行擴展,遇到坑也不一定能填。

如果自己造輪子的話,還需要我們花時間去驗證去適應我們的業務需求,但好處是我們可以自己去擴展可把控,不過這很考量開發者的素質。

數據解析

實際開發當中服務端的返回數據格式無非就兩種:
- JSON
- XML

這兩種格式數據格式各有優劣,從可讀性來看,xml略微好一點,不過JSON也有規范的標簽,從解析難度和速度來看,大家都比較傾向使用JSON,目前JSON也是主流的數據格式。

在Android中均可以使用優秀的解析庫來加快我們的解析速度,XML中有dom4j,JSON有Jackson、Gson,我們通過這些庫實現我們更快的完成數據解析,提高我們的開發效率。

數據存儲

上一節講的是數據解析,我們解析完后的數據,可能就需要將數據存儲在某個地方,Android的五種存儲方式:
- Content Provider(主要用來向其他應用程序共享數據)
- SQLite(存儲數據到數據庫中)
- File(本地文件保存)
- SharedPreference(主要用來保存簡單的配置信息)
- 網絡存儲(WebService返回的數據或是解析HTTP協議實現網絡數據交互)

為了提高應用程序的響應時間,數據緩存是一個比較好的方式,我們可以預處理服務器返回的數據,對數據進行緩存刷新。

優化點:
- 異步請求網絡數據
- 預處理服務器返回數據
- 異步進行數據存儲操作
- 數據緩存刷新
- Timeout超時重試
- 在主線程中操作UI

界面卡頓

ANR表示”應用程序無響應”,這個是需要我們避免發生的事情,出現這個異常的原因:
- 主線程 (“事件處理線程” / “UI線程”) 在5秒內沒有響應輸入事件
- BroadcastReceiver在10秒內沒有執行完畢

導致ANR的原因有很多,一般情況就是在UI線程做了耗時的操作,例如”網絡請求”、數據庫操作。

那么如何避免?
- UI線程只做界面刷新,不做任何耗時操作,耗時操作放在子線程來做
- 可以使用Thread+handle或者AsyncTask來進行邏輯處理

耗內存

每部手機的內存有限,我們這里所說的內存指的是手機的RAM,它是Ramdom Access Memory的縮寫,我們應用程序的需要隨機讀寫的數據就存在RAM中,Android手機之所以會比較耗內存,這跟Android后臺的處理有關,我們知道Android應用是使用Java開發的,運行Java需要有虛擬機,說明每開啟一個應用都會創建一個虛擬機,而這是需要內存的,所以我們開的應用越多,后臺進程越多,內存都分配出去了,才導致內存消耗的嚴重。

其實這個問題我們是沒得破的,只要內存不夠,我們的應用還是會卡。我們開發的應用依賴與系統給我們分配的堆內存,一般上限在16M~48M,但我們可以通過在AndroidManifest設置Application屬性largeHeap=“true”來申請更多的堆內存。

通過以下代碼獲取可用堆內存限制:

mActivityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);mMaxMemory = mActivityManager.getMemoryClass();

內存泄露

內存泄露這個問題已經被說爛了,大家都知道有內存泄露這個問題存在,但為什么會發生內存泄露?

這里的內存泄露并不是真正意思上的泄露,而是因為內存不足不能進行GC操作,從而導致占用內存過大,拋出out of memory異常,而被系統Kill掉。

JVM回收機制

是時候講講JVM的回收機制了,看下圖:

JVM對Java對象分了三個代進行管理,分別為年輕代、年老代、永久代。
年輕代(Young Generation):絕大多數的Java對象會在年輕代被分配,也會在年輕代被回收。
年老代(Old Generation):在年輕代長期存在沒有被回收的Java對象會轉移到年老代,這個堆空間通常會被比年輕代的堆空間要大。
永久代:存放VM和Java類的元數據,以及interned字符串和類的靜態變量。

這里涉及到JVM的相關知識,這里不繼續深入探討。

但我們應該可以知道垃圾回收器的作用:
- 分配內存
- 保證所有正在被引用的對象還存在于內存中
- 回收執行代碼已經不再引用的對象所占的內存

對象引用

Java的引用類型可以分為以下幾種:
- 強引用(Strong Ref):強可達,去掉強可達,才會被回收。
- 軟引用(Soft Ref):內存夠用,就保持,內存吃緊,則回收,主要用來做緩存。
- 弱引用(Weak Ref):比Soft Ref弱,即使內存不吃緊也會被回收。
- 虛引用(Phantom Ref):不會在內存保持任何對象。

一圖勝千言:

利用Strong Ref,存儲大量數據,直到heap撐破,利用inter strings(或者class loader加載大量的類)把perm gen撐破,然后就是內存泄露了。

如何優化?

前面講了一些背景知識,對我們理解內存優化有一定的幫助,下面就簡單說一下我們優化的方向:
- 布局優化
- 內存優化

布局優化

大家可以拿出你們的Android機
開發者工具-Profile GPU Rendering-選擇在屏幕上顯示條形圖

-藍色代表測量繪制Display List的時間
-紅色代表OpenGL渲染Display List所需要的時間
-黃色代表CPU等待GPU處理的時間
-中間綠色橫線代表VSYNC時間16ms,盡量將所有條形圖控制在這條綠線下

為什么是16ms?

Android 通知界面渲染和重繪的時間要在16ms內完成,如果超過16ms,就會導致丟幀,也就是我們常說的卡頓。

優化點:
- 避免OverDraw
- 優化布局層級
- 避免過多無用嵌套
- 使用<include>標簽重用layout
- 使用<ViewStub>延遲加載
- Hierarchy View進行層級分析

具體的使用方法,這里不介紹了,不懂就百度。

內存優化

內存優化的點有很多,這里我主要分為兩大塊:
- Bitmap優化
- 代碼優化

Bitmap優化

  • 使用適當分辨率和大小的圖片
  • 及時回收內存(bitmap.recycle())
  • 使用圖片緩存(LruCache和DiskLruCache)
  • 第一點,就是按需顯示,比如列表中的圖片,你可以顯示縮略圖,詳情頁,你就可以加載相應的分辨率的圖片,這樣可以減少內存消耗,一般可以要求服務端提供多種分辨率的圖片。

    第二點,Bitmap是很耗內存,尤其是加載比較大的bitmap,可以想到的優化方案就是使用記得回收,對Bitmap進行壓縮,使用BitmapFactory.Options設置inSampleSize就可以縮小圖片。

    第三點,圖像緩存,這個可以利用成熟的圖片加載框架,比如Universal-ImageLoader、Fresco、Picasso,這些框架都對圖片進行了很好的優化,大家可以對比一下,選擇使用即可。

    代碼優化

    關于代碼這個就有的說了,任何能改進我們程序的優化點都能寫在這里,這里沒辦法把所有優化的點列在這里,只提供相關的參考,剩下的就好各位經驗總結和積累了。

    優化點:
    - 對常量使用static修飾符
    - 使用靜態方法
    - 減少不必要的成員變量
    - 盡量不要使用枚舉,少用迭代器
    - 對Cursor、Receiver、Sensor、File等對象,要注意它們的創建、回收與注冊、反注冊
    - 避免大量使用注解、反射
    - 使用RenderScript、OpenGL來進行復雜的繪圖操作
    - 使用SurfaceView來替代View進行大量、頻繁的繪圖操作
    - 盡量使用視圖緩存,而不是每次都執行inflate()方法解析視圖

    注:這里引用了Android群英傳的相關優化點

    • 創建新的對象都需要額外的內存空間,要盡量減少創建新的對象。
    • 將類、變量、方法等等的可見性修改為最小。
    • 針對字符串的拼接,使用StringBuffer替代String。
    • 不要在循環當中聲明臨時變量,不要在循環中捕獲異常。
    • 如果對于線程安全沒有要求,盡量使用線程不安全的集合對象。
    • 使用集合對象,如果事先知道其大小,則可以在構造方法中設置初始大小。
    • 文件讀取操作需要使用緩存類,及時關閉文件。
    • 慎用異常,使用異常會導致性能降低。
    • 如果程序會頻繁創建線程,則可以考慮使用線程池。

    以上都是些經驗總結,大致都相差無幾,朋友們在做代碼優化的時候,可以根據這些優化點,有針對性去重構代碼,其實最重要還是代碼的可讀性,結構清晰。

    性能優化工具

    • Memory Monitor - 內存監視工具
    • TraceView
    • MAT

    Android開發者對與以上幾個性能調優的工具一定不陌生,這里我也不再寫那么多廢話了,關于它們的使用方法,官網還有一些大牛的博客都有介紹。

    最后

    寫這篇文章的出發點也是對Android性能優化有個比較清楚的認識,任何事情都不可能一蹴而就,需要循循漸進,對一個初學者你談優化很不現實,我們先把基本的做好,再去考慮相應的優化,筆者也在不斷學習當中,借鑒別人好的優化方案,提高產品的質量,感謝大家對筆者的關注。

    總結

    以上是生活随笔為你收集整理的App性能优化浅谈的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。