Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android進階:性能優化篇

Android進階:性能優化篇

編輯:Android開發實例

一、在使用Gallery控件時,如果載入的圖片過多,過大,就很容易出現OutOfMemoryError異常,就是內存溢出。這是因為Android默認分配的內存只有幾M,而載入的圖片如果是JPG之類的壓縮格式,在內存中展開時就會占用大量的空間,也就容易內存溢出。這時可以用下面的方法解決:

  1. ImageView i = new ImageView(mContext);  
  2.           BitmapFactory.Options options=new BitmapFactory.Options();  
  3.           options.inSampleSize = 10;  
  4.           //貌似這個options的功能是返回縮略圖,10即表示長和寬為原來的1/10,即面積為原來的1/100  
  5.           //縮略圖可以減少內存占用  
  6.           Bitmap bm = BitmapFactory.decodeFile(lis.  
  7.                                 get(position).toString(),options);  
  8.           i.setImageBitmap(bm);  
  9.           bm.recycle();  
  10.           //資源回收 

 

二、統一管理位圖資源,適時釋放資源

 

  1. class ImageManager {     
  2.     private WeakHashMap<Integer, WeakReference<Bitmap>> mBitmaps;     
  3.     private WeakHashMap<Integer, WeakReference<Drawable》> mDrawables;     
  4.     
  5.     private boolean mActive = true;     
  6.     
  7.     public ImageManager() {     
  8.         mBitmaps = new WeakHashMap<Integer, WeakReference<Bitmap>>();     
  9.         mDrawables = new WeakHashMap<Integer, WeakReference<Drawable>>();     
  10.     }     
  11.     
  12.    
  13.     public Bitmap getBitmap(int resource) {     
  14.         if (mActive) {     
  15.             if (!mBitmaps.containsKey(resource)) {     
  16.                 mBitmaps.put(resource,     
  17.                     new WeakReference<Bitmap>(BitmapFactory.decodeResource(MainActivity.getContext().getResources(), resource)));     
  18.             }     
  19.             return ((WeakReference<Bitmap>)mBitmaps.get(resource)).get();     
  20.         }     
  21.         return null;     
  22.     }     
  23.     
  24.     public Drawable getDrawable(int resource) {     
  25.         if (mActive) {     
  26.             if (!mDrawables.containsKey(resource)) {     
  27.                 mDrawables.put(resource, new WeakReference<Drawable>(getApplication().getResources().getDrawable(resource)));     
  28.             }     
  29.             return ((WeakReference<Drawable>)mDrawables.get(resource)).get();     
  30.         }     
  31.         return null;     
  32.     }     
  33.     
  34.     public void recycleBitmaps() {     
  35.         Iterator itr = mBitmaps.entrySet().iterator();     
  36.         while (itr.hasNext()) {     
  37.             Map.Entry e = (Map.Entry)itr.next();     
  38.             ((WeakReference<Bitmap>) e.getValue()).get().recycle();     
  39.         }     
  40.         mBitmaps.clear();     
  41.     }     
  42.     
  43.     public ImageManager setActive(boolean b) {     
  44.         mActive = b;     
  45.         return this;     
  46.     }     
  47.     
  48.     public boolean isActive() {     
  49.         return mActive;     
  50.     }     
  51. }   

 

三、網絡連接往往是耗電量比較大的 那我們可以優化一下在需要網絡連接的程序中,首先檢查網絡連接是否正常,如果沒有網絡連接,那麼就不需要執行相應的程序。


檢查網絡連接的方法如下:

 

 

  1. private boolean isConnected(){  
  2.         ConnectivityManager mConnectivity = (ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE);    
  3.         TelephonyManager mTelephony = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);  
  4.           
  5.         // 檢查網絡連接,如果無網絡可用,就不需要進行連網操作等  
  6.         NetworkInfo info = mConnectivity.getActiveNetworkInfo();  
  7.         if (info == null ||  
  8.                 !mConnectivity.getBackgroundDataSetting()) {  
  9.                 return false;  
  10.         }  
  11.         //判斷網絡連接類型,只有在3G或wifi裡進行一些數據更新。  
  12.         int netType = info.getType();  
  13.         int netSubtype = info.getSubtype();  
  14.         if (netType == ConnectivityManager.TYPE_WIFI) {  
  15.             return info.isConnected();  
  16.         } else if (netType == ConnectivityManager.TYPE_MOBILE  
  17.                 && netSubtype == TelephonyManager.NETWORK_TYPE_UMTS  
  18.                 && !mTelephony.isNetworkRoaming()) {  
  19.             return info.isConnected();  
  20.         } else {  
  21.             return false;  
  22.         }  
  23.     } 

 

四、網絡間的數據傳輸也是非常耗費資源的,這包括傳輸方式和解析方式

 

來看一個表格

 

 

其中 Tree Parse 是DOM解析 Event/Stream是SAX方式解析

 

很明顯,使用流的方式解析效率要高一些,因為DOM解析是在對整個文檔讀取完後,再根據節點層次等再組織起來。而流的方式是邊讀取數據邊解析,數據讀取完後,解析也就完畢了。

 

在數據格式方面,JSON和Protobuf效率明顯比XML好很多,XML和JSON大家都很熟悉。

 

從上面的圖中我們可以得出結論就是盡量使用SAX等邊讀取邊解析的方式來解析數據,針對移動設備,最好能使用JSON之類的輕量級數據格式為佳。

 

五、傳輸數據經過壓縮 目前大部門網站都支持GZIP壓縮,所以在進行大數據量下載時,盡量使用GZIP方式下載,可以減少網絡流量。

使用方法如下所示:

 

  1. HttpGet request =  
  2.         new HttpGet("http://example.com/gzipcontent");  
  3.     HttpResponse resp =  
  4.         new DefaultHttpClient().execute(request);  
  5.     HttpEntity entity = response.getEntity();  
  6.     InputStream compressed = entity.getContent();  
  7.     InputStream rawData = new GZIPInputStream(compressed); 

 

六、有效管理Service 後台服務就相當於一個持續運行的Acitivity  如果開發的程序後台都會一個service不停的去服務器上更新數據,在不更新數據的時候就讓它sleep,這種方式是非常耗電的,通常情況下,我們可以使用AlarmManager來定時啟動服務。如下所示,第30分鐘執行一次。

 

 

  1. AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);  
  2.         Intent intent = new Intent(context, MyService.class);  
  3.         PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);  
  4.         long interval = DateUtils.MINUTE_IN_MILLIS * 30;  
  5.         long firstWake = System.currentTimeMillis() + interval;  
  6.         am.setRepeating(AlarmManager.RTC,firstWake, interval, pendingIntent); 

 

開發過程中應該注意一些細節,並經手機的整體性能和續航都是有很大的局限,很多個優化的細節會對軟件產生本質的影響,這些需要引起重視,也要在開發過程中不斷積累

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved