自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android開發(fā)優(yōu)化之——從代碼角度進(jìn)行優(yōu)化

移動(dòng)開發(fā) Android
通常我們寫程序,都是在項(xiàng)目計(jì)劃的壓力下完成的,此時(shí)完成的代碼可以完成具體業(yè)務(wù)邏輯,但是性能不一定是最優(yōu)化的。一般來說,優(yōu)秀的程序員在寫完代碼之后都會不斷的對代碼進(jìn)行重構(gòu)。重構(gòu)的好處有很多,其中一點(diǎn),就是對代碼進(jìn)行優(yōu)化,提高軟件的性能。下面我們就從幾個(gè)方面來了解Android開發(fā)過程中的代碼優(yōu)化。

通常我們寫程序,都是在項(xiàng)目計(jì)劃的壓力下完成的,此時(shí)完成的代碼可以完成具體業(yè)務(wù)邏輯,但是性能不一定是***化的。一般來說,優(yōu)秀的程序員在寫完代碼之后都會不斷的對代碼進(jìn)行重構(gòu)。重構(gòu)的好處有很多,其中一點(diǎn),就是對代碼進(jìn)行優(yōu)化,提高軟件的性能。下面我們就從幾個(gè)方面來了解Android開發(fā)過程中的代碼優(yōu)化。

1)靜態(tài)變量引起內(nèi)存泄露

在代碼優(yōu)化的過程中,我們需要對代碼中的靜態(tài)變量特別留意。靜態(tài)變量是類相關(guān)的變量,它的生命周期是從這個(gè)類被聲明,到這個(gè)類徹底被垃圾回收器回收才會被銷毀。所以,一般情況下,靜態(tài)變量從所在的類被使用開始就要一直占用著內(nèi)存空間,直到程序退出。如果不注意,靜態(tài)變量引用了占用大量內(nèi)存的資源,造成垃圾回收器無法對內(nèi)存進(jìn)行回收,就可能造成內(nèi)存的浪費(fèi)。

先來看一段代碼,這段代碼定義了一個(gè)Activity。

  1. private static Resources mResources;   
  2.  
  3. @Override 
  4.  
  5. protected void onCreate(Bundle state) { 
  6.  
  7. super.onCreate(state); 
  8.  
  9. if (mResources == null) { 
  10.  
  11.     mResources = this.getResources(); 
  12.  
  13.     } 
  14.  
  15.   

這段代碼中有一個(gè)靜態(tài)的Resources對象。代碼片段mResources = this.getResources()對Resources對象進(jìn)行了初始化。這時(shí)Resources對象擁有了當(dāng)前Activity對象的引用,Activity又引用了整個(gè)頁面中所有的對象。

如果當(dāng)前的Activity被重新創(chuàng)建(比如橫豎屏切換,默認(rèn)情況下整個(gè)Activity會被重新創(chuàng)建),由于Resources引用了***次創(chuàng)建的Activity,就會導(dǎo)致***次創(chuàng)建的Activity不能被垃圾回收器回收,從而導(dǎo)致***次創(chuàng)建的Activity中的所有對象都不能被回收。這個(gè)時(shí)候,一部分內(nèi)存就浪費(fèi)掉了。

經(jīng)驗(yàn)分享:

在實(shí)際項(xiàng)目中,我們經(jīng)常會把一些對象的引用加入到集合中,如果這個(gè)集合是靜態(tài)的話,就需要特別注意了。當(dāng)不需要某對象時(shí),務(wù)必及時(shí)把它的引用從集合中清理掉?;蛘呖梢詾榧咸峁┮环N更新策略,及時(shí)更新整個(gè)集合,這樣可以保證集合的大小不超過某值,避免內(nèi)存空間的浪費(fèi)。

2)使用Application的Context

在Android中,Application Context的生命周期和應(yīng)用的生命周期一樣長,而不是取決于某個(gè)Activity的生命周期。如果想保持一個(gè)長期生命的對象,并且這個(gè)對象需要一個(gè)Context,就可以使用Application對象??梢酝ㄟ^調(diào)用Context.getApplicationContext()方法或者Activity.getApplication()方法來獲得Application對象。

依然拿上面的代碼作為例子??梢詫⒋a修改成下面的樣子。

  1. private static Resources mResources;   
  2.  
  3. @Override 
  4.  
  5. protected void onCreate(Bundle state) { 
  6.  
  7. super.onCreate(state); 
  8.  
  9. if (mResources == null) { 
  10.  
  11.     // mResources = this.getResources(); 
  12.  
  13.     mResources = this.getApplication().getResources(); 
  14.  
  15.     } 
  16.  
  17.   

在這里將this.getResources()修改為this.getApplication().getResources()。修改以后,Resources對象擁有的是Application對象的引用。如果Activity被重新創(chuàng)建,***次創(chuàng)建的Activity就可以被回收了。

3)及時(shí)關(guān)閉資源

Cursor是Android查詢數(shù)據(jù)后得到的一個(gè)管理數(shù)據(jù)集合的類。正常情況下,如果我們沒有關(guān)閉它,系統(tǒng)會在回收它時(shí)進(jìn)行關(guān)閉,但是這樣的效率特別低。如果查詢得到的數(shù)據(jù)量較小時(shí)還好,如果Cursor的數(shù)據(jù)量非常大,特別是如果里面有Blob信息時(shí),就可能出現(xiàn)內(nèi)存問題。所以一定要及時(shí)關(guān)閉Cursor。

下面給出一個(gè)通用的使用Cursor的代碼片段。

  1. Cursor cursor = null
  2.  
  3. try
  4.  
  5.     cursor = mContext.getContentResolver().query(uri,null,null,null,null); 
  6.  
  7.     if (cursor != null) { 
  8.  
  9.         cursor.moveToFirst(); 
  10.  
  11.         // 處理數(shù)據(jù) 
  12.  
  13.     } 
  14.  
  15. catch (Exception e){ 
  16.  
  17.     e.printStatckTrace(); 
  18.  
  19. finally { 
  20.  
  21.     if (cursor != null){ 
  22.  
  23.         cursor.close(); 
  24.  
  25.     } 
  26.  
  27.   

即對異常進(jìn)行捕獲,并且在finally中將cursor關(guān)閉。

同樣的,在使用文件的時(shí)候,也要及時(shí)關(guān)閉。

4)使用Bitmap及時(shí)調(diào)用recycle()

前面的章節(jié)講過,在不使用Bitmap對象時(shí),需要調(diào)用recycle()釋放內(nèi)存,然后將它設(shè)置為null。雖然調(diào)用recycle()并不能保證立即釋放占用的內(nèi)存,但是可以加速Bitmap的內(nèi)存的釋放。

在代碼優(yōu)化的過程中,如果發(fā)現(xiàn)某個(gè)Activity用到了Bitmap對象,卻沒有顯式的調(diào)用recycle()釋放內(nèi)存,則需要分析代碼邏輯,增加相關(guān)代碼,在不再使用Bitmap以后調(diào)用recycle()釋放內(nèi)存。

5)對Adapter進(jìn)行優(yōu)化

下面以構(gòu)造ListView的BaseAdapter為例說明如何對Adapter進(jìn)行優(yōu)化。

在BaseAdapter類中提供了如下方法:

  1. public View getView(int position, View convertView, ViewGroup parent) 
  2.  

當(dāng)ListView列表里的每一項(xiàng)顯示時(shí),都會調(diào)用Adapter的getView方法返回一個(gè)View,

來向ListView提供所需要的View對象。

下面是一個(gè)完整的getView()方法的代碼示例。

  1. public View getView(int position, View convertView, ViewGroup parent) { 
  2.  
  3.   ViewHolder holder; 
  4.  
  5. if (convertView == null) { 
  6.  
  7.       convertView = mInflater.inflate(R.layout.list_item, null); 
  8.  
  9.       holder = new ViewHolder(); 
  10.  
  11.       holder.text = (TextView) convertView.findViewById(R.id.text); 
  12.  
  13.       convertView.setTag(holder); 
  14.  
  15.   } else { 
  16.  
  17.       holder = (ViewHolder) convertView.getTag(); 
  18.  
  19.   } 
  20.  
  21.   holder.text.setText("line" + position); 
  22.  
  23.   return convertView; 
  24.  
  25.  
  26.   
  27.  
  28. private class ViewHolder { 
  29.  
  30.   TextView text; 
  31.  
  32.   

當(dāng)向上滾動(dòng)ListView時(shí),getView()方法會被反復(fù)調(diào)用。getView()的第二個(gè)參數(shù)convertView是被緩存起來的List條目中的View對象。當(dāng)ListView滑動(dòng)的時(shí)候,getView可能會直接返回舊的convertView。這里使用了convertView和ViewHolder,可以充分利用緩存,避免反復(fù)創(chuàng)建View對象和TextView對象。

如果ListView的條目只有幾個(gè),這種技巧并不能帶來多少性能的提升。但是如果條目有幾百甚至幾千個(gè),使用這種技巧只會創(chuàng)建幾個(gè)convertView和ViewHolder(取決于當(dāng)前界面能夠顯示的條目數(shù)),性能的差別就非常非常大了。

6)代碼“微優(yōu)化”

當(dāng)今時(shí)代已經(jīng)進(jìn)入了“微時(shí)代”。這里的“微優(yōu)化”指的是代碼層面的細(xì)節(jié)優(yōu)化,即不改動(dòng)代碼整體結(jié)構(gòu),不改變程序原有的邏輯。盡管Android使用的是Dalvik虛擬機(jī),但是傳統(tǒng)的Java方面的代碼優(yōu)化技巧在Android開發(fā)中也都是適用的。

下面簡要列舉一部分。因?yàn)橐话鉐ava開發(fā)者都能夠理解,就不再做具體的代碼說明。

創(chuàng)建新的對象都需要額外的內(nèi)存空間,要盡量減少創(chuàng)建新的對象。

將類、變量、方法等等的可見性修改為最小。

針對字符串的拼接,使用StringBuffer替代String。

不要在循環(huán)當(dāng)中聲明臨時(shí)變量,不要在循環(huán)中捕獲異常。

如果對于線程安全沒有要求,盡量使用線程不安全的集合對象。

使用集合對象,如果事先知道其大小,則可以在構(gòu)造方法中設(shè)置初始大小。

文件讀取操作需要使用緩存類,及時(shí)關(guān)閉文件。

慎用異常,使用異常會導(dǎo)致性能降低。

如果程序會頻繁創(chuàng)建線程,則可以考慮使用線程池。

經(jīng)驗(yàn)分享:

代碼的微優(yōu)化有很多很多東西可以講,小到一個(gè)變量的聲明,大到一段算法。尤其在代碼Review的過程中,可能會反復(fù)審查代碼是否可以優(yōu)化。不過我認(rèn)為,代碼的微優(yōu)化是非常耗費(fèi)時(shí)間的,沒有必要從頭到尾將所有代碼都優(yōu)化一遍。開發(fā)者應(yīng)該根據(jù)具體的業(yè)務(wù)邏輯去專門針對某部分代碼做優(yōu)化。比如應(yīng)用中可能有一些方法會被反復(fù)調(diào)用,那么這部分代碼就值得專門做優(yōu)化。其它的代碼,需要開發(fā)者在寫代碼過程中去注意。

責(zé)任編輯:張葉青 來源: 技術(shù)博客
相關(guān)推薦

2013-02-20 14:32:37

Android開發(fā)性能

2022-07-15 13:01:13

Kotlin編程語言Java

2013-09-16 16:56:09

AndroidBitmap內(nèi)存優(yōu)化

2013-09-16 15:50:04

Android優(yōu)化界面UI

2013-09-16 15:33:28

Android優(yōu)化界面UI

2013-09-16 15:42:00

Android優(yōu)化界面UI

2021-07-29 14:20:34

網(wǎng)絡(luò)優(yōu)化移動(dòng)互聯(lián)網(wǎng)數(shù)據(jù)存儲

2017-12-23 14:38:41

Android編程開發(fā)優(yōu)化

2019-12-13 10:25:08

Android性能優(yōu)化啟動(dòng)優(yōu)化

2024-12-10 00:00:10

MySQLJOIN算法

2011-06-14 11:14:10

性能優(yōu)化代碼

2017-07-26 13:56:26

Android權(quán)限優(yōu)化

2011-11-02 17:17:06

jQuery

2013-09-17 10:32:08

Android性能優(yōu)化數(shù)據(jù)庫

2017-01-15 15:13:37

Android性能優(yōu)化優(yōu)化點(diǎn)

2011-06-22 17:11:18

SEO

2015-09-16 15:48:55

Android性能優(yōu)化電量

2015-09-16 14:37:50

Android性能優(yōu)化運(yùn)算

2015-09-16 13:54:30

Android性能優(yōu)化渲染

2017-01-19 15:27:24

Android性能優(yōu)化Lint
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號