ANDROID 開發規範總結

ANDROID 開發規範總結

 

基本原則

工欲善其事,必先利其器

充分利用好工具,讓電腦代替人腦

 

最高境界是不寫任何代碼

和產品人員充分討論,仔細評估待實現的功能,明確方案,不做無用功(最好能把需求砍掉J)

 

爲質量負責

 提交代碼前仔細檢查,找同事幫忙review

 如果迫不得已,挖坑前做好標記(TODO)

 

工具和開發環境

開發推薦使用eclipse,或者類eclipse環境

配置好Android Formatter

配置好Save Actions

Formatter配置

Eclipse -> Window -> Preferences

 

 Import 導入相應的formatter.xml文件

 


Save Actions配置

eclipse -> Window -> Preferences

 

配置成如上的形式就可以了。


UI編碼規範

不要阻塞UI線程

1、UI線程內不能做耗時操作,如文件讀寫、數據庫操作、邏輯運算等,建議每次調用耗時不超過10ms,如果超過,建議在工作線程內完成。

2、使用trace view查找耗時方法。

3、使用StrictMode監測耗時操作。

優化高頻率運行的代碼

1、不頻繁進行findViewById、getString…等查找資源的操作, 應使用臨時對象緩存。

2、避免頻繁創建對象

     –自定義View不能每幀刷新都去創建新的Paint、Rect、Matrix等對象,應使用臨時對象緩存,一次性創建並初始化,每次直接使用。

     –當需要重複使用Bitmap時,不要頻繁進行decode,而應將其緩存在cache中。(注:安卓3.0以下可使用軟引用cache,3.0以上使用LRU cache並需自己做好內存控制。 爲了統一和適配,建議使用後者”)。

避免過度刷新

主要是item很多的ListView的過度刷新

1、  不要頻繁調用Adapter的notifyDataSetChanged方法,只更新需要被更新的行。

常見的場景:後臺頻繁更新數據,界面接收到回調後直接notifyDataSetChanged。正確的方法:判斷後臺數據對應的行是否可見,然後刷新該View。

2、listview滑動的過程中少調用notifyDataSetChanged。

3、Adapter需使用複用機制,不能每次getView都去重新inflate, 應儘量利用convertView 和 ViewHolder來實現複用機制。

佈局扁平化

1、  多使用merge、ViewStub標籤。

2、使用RelativeLayout代替多級Linearlayout。

3、使用hierarchy view排查佈局問題。

不使用大尺寸圖片

1、使用BitmapFactory類的decode函數生成bitmap時,調整採樣間隔和縮放尺寸,進行預縮放處理

2、避免使用多套分辨率圖片

爲了保證不同分辨率手機ui效果,可能會在hdpi、xhdpi等目錄下各保持一份圖片,這樣做會增加apk體積,儘量只放一套圖片,然後指定View的高寬,在不同分辨率下定義不同的dimen。

正確使用inflate方法

不正確的使用inflate(Contextcontext, int resource, ViewGroup root)方法導致View Hierarchy多嵌套了一層,會導致View效率低下。

錯誤的作法:

正確的做法:

解決辦法:在inflate第三個參數給定root的時候,應該在xml文件中用merge標籤消除嵌套,並且在代碼中設置相關屬性(xml文件中使用merge標籤,對這一標籤的任何屬性都將失效,包括id,可以看作沒有這一層)。

使用ColorFilter節省圖片資源

一個按鈕擁有多種狀態,爲滿足這些狀態使用了不同的切圖

儘可能的使用ColorFilter,使用ColorFilter可節省50%內存使用

界面元素儘量少且簡單

如果一個Activity展示的元素過多,肯定會影響性能,可以考慮下面的方法:

1、把業務邏輯分拆到不同的界面。

2、使用Fragment展示不同的界面。

3、使用自定義Layout展示不同的界面,不同的情況切換不同的Layout。

UI邏輯和業務邏輯分離

如果activity邏輯很複雜,建議將UI和業務邏輯放到單獨的類實現,用Message傳遞消息,

Adapter數據變化問題

如果在非ui線程修改Adapter內容(增加item),會拋出下面的異常:

java.lang.IllegalStateException: Thecontent of the adapter has changed but ListView did not receive a notification.Make sure the content of your adapter is not modified from a background thread,but only from the UI thread

修改方法是在UI線程中修改,可以通過Handler解決數據傳遞問題。

使用include複用layout

Include可以減少重複資源,佈局文件更清晰。

設置窗口背景爲null

<item name="android:windowBackground">@null</item>

可以省去window背景的繪製,提高界面效率

 

實踐經驗

修復BUG時,避免簡單粗暴

修復BUG時,要儘量找到問題的根本原因。不要直接加上try/catch完事。

 

避免Context對象使用強制類型轉換

避免使用Context轉換爲Activity,禁止使用Context轉換爲Application。

持有Context對象

儘量用context.getApplicationContext代替

 

誰申請誰釋放原則

Receiver的註冊和註銷,包括Android的和LocalBroadcastManager

Service的bind和unbind

一定要保證成對出現,否則導致內存泄漏

Fragment的細節

Fragment的onCreateView/onDestroy/handleMessage,要判斷Activity是否爲空,是否finish

 

Fragment繼承注意事項

繼承Fragment的子類,其構造函數必須是無參數的,需要的Activity父對象可以通過onAttach(Activity)來傳遞。

 

public Activity mContext;

 

   @Override

   public void onAttach(Activity activity) {

       super.onAttach(activity);

       this.mContext = activity;

}

 

否則會報告如下錯誤:

 

Caused by:android.support.v4.app.Fragment$InstantiationException: Unable to instantiatefragment alj: make sure class name exists, is public, and has an emptyconstructor that is public

        at android.support.v4.app.Fragment.instantiate(Fragment.java:395)   com.qihoo360.mobilesafe.ui.fragment.settings.SettingsView -> alj

        at android.support.v4.app.FragmentState.instantiate(Fragment.java:96)

        atandroid.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1726)

        at android.suppo

 

Dialog的show/dismiss

需要判斷Activity是否finish

 

AsyncTask的onPost

需要判斷Activity是否finish

 

Android的Receiver上下文

Android的Receiver上下文是限制上下文,不能用其Context去bindService操作

 

Handler/Runnable內存泄漏

要小心Handler/Runnable對Activity等的長期持有

 

AsyncTask內存泄漏

要小心AsyncTask對Activity等的長期持有

 

Toast使用

Toast最好在UI線程中啓動,否則可能會報錯:

 

04-17 19:04:29.424: E/CrashHandler(11689):Crash Log BEGIN

04-17 19:04:29.424: E/CrashHandler(11689):java.lang.RuntimeException: Can't create handler inside thread that has notcalled Looper.prepare()

04-17 19:04:29.424: E/CrashHandler(11689):at android.os.Handler.<init>(Handler.java:121)

04-17 19:04:29.424: E/CrashHandler(11689):at android.widget.Toast$TN.<init>(Toast.java:317)

04-17 19:04:29.424: E/CrashHandler(11689):at android.widget.Toast.<init>(Toast.java:91)

 

明文字符串

儘量不要在傳輸中直接傳輸明文字符串。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章