Android的一些編碼規範和優化

desaco發表於2016-01-26

--------------------------------------------------------------------------------  

 一、Android編碼規範

  1.java程式碼中不出現中文,最多註釋中可以出現中文;
  2.區域性變數命名、靜態成員變數命名:只能包含字母,單詞首字母出第一個都為大寫,其他字母都為小寫;
  3.常量命名:只能包含字母和_,字母全部大寫,單詞之間用_隔開;
  4.layout中的id命名:命名模式為:view縮寫_模組名稱_view的邏輯名稱view的縮寫詳情如下 LinearLayoutllRelativeLayout:rlTextView:tvImageView:ivImageButton:ibButton:btn
  5.activity中的view變數命名命名模式為:view縮寫+邏輯名稱建議:如果layout檔案很複雜,建議將layout分成多個模組,每個模組定義一個moduleViewHolder,其成員變數 包含所屬view
  6.strings.xml中的id命名:命名模式:activity名稱_功能模組名稱_邏輯名稱     activity名稱_邏輯名稱      common_邏輯名稱strings.xml中,使用activity名稱註釋,將檔案內容區 分開來
  7.drawable中的圖片命名命名模式:activity名稱_邏輯名稱/common_邏輯名稱7.styles.xml:將layout中不斷重現的style提煉出通用的style通用元件,放到styles.xml中;
  8.使用layer-list和selector
  9.圖片儘量分拆成多個可重用的圖片
 10.服務端可以實現的,就不要放在客戶端
 11.引用第三方庫要慎重,避免應用大容量的第三方庫,導致客戶端包非常大
 12.處理應用全域性異常和錯誤,將錯誤以郵件的形式傳送給服務端
 13.圖片的.9處理
 14.使用靜態變數方式實現介面間共享要慎重
15.Log(系統名稱 模組名稱 介面名稱,詳細描述)
16.單元測試(邏輯測試、介面測試)
17.不要重用父類的handler,對應一個類的handler也不應該讓其子類用到,否則會導致message.what衝突
18.activity中在一個View.OnClickListener中處理所有的邏輯
19.strings.xml中使用%1$s實現字串的通配
 20.如果多個Activity中包含共同的UI處理,那麼可以提煉一個CommonActivity,把通用部分叫由它來處理,其他activity只要繼承它即可
 21.使用button+activitgroup實現tab效果時,使用Button.setSelected(true),確保按鈕處於選擇狀態,並使activitygroup的當前activity與該button對應
 22.如果所開發的為通用元件,為避免衝突,將drawable/layout/menu/values目錄下的檔名增加字首
 23.資料一定要效驗,例如字元型轉數字型,如果轉換失敗一定要有預設值;服務端響應資料是否有效判斷;

  二、Android效能優化
  1.http用gzip壓縮,設定連線超時時間和響應超時時間
http請求按照業務需求,分為是否可以快取和不可快取,那麼在無網路的環境中,仍然通過快取的httpresponse瀏覽部分資料,實現離線閱讀。
  2.listview 效能優化
1).複用convertView
在getItemView中,判斷convertView是否為空,如果不為空,可複用。如果couvertview中的view需要新增listerner,程式碼一定要在if(convertView==null){}之外。
2).非同步載入圖片
item中如果包含有webimage,那麼最好非同步載入
3).快速滑動時不顯示圖片
當快速滑動列表時(SCROLL_STATE_FLING),item中的圖片或獲取需要消耗資源的view,可以不顯示出來;而處於其他兩種狀態(SCROLL_STATE_IDLE 和SCROLL_STATE_TOUCH_SCROLL),則將那些view顯示出來
 3.使用執行緒池,分為核心執行緒池和普通執行緒池,下載圖片等耗時任務放置在普通執行緒池,避免耗時任務阻塞執行緒池後,導致所有非同步任務都必須等待
 4.非同步任務,分為核心任務和普通任務,只有核心任務中出現的系統級錯誤才會報錯,非同步任務的ui操作需要判斷原activity是否處於啟用狀態
 5.儘量避免static成員變數引用資源耗費過多的例項,比如Context
 6.使用WeakReference代替強引用,弱引用可以讓您保持對物件的引用,同時允許GC在必要時釋放物件,回收記憶體。對於那些建立便宜但耗費大量記憶體的物件,即希望保持該物件,又要在應用程式需要時使用,同時希望GC必要時回收時,可以考慮使用弱引用。
 7.超級大胖子Bitmap
及時的銷燬(Activity的onDestroy時,將bitmap回收)
設定一定的取樣率
巧妙的運用軟引用
drawable對應resid的資源,bitmap對應其他資源
 8.保證Cursor 佔用的記憶體被及時的釋放掉,而不是等待GC來處理。並且 Android明顯是傾向於程式設計者手動的將Cursor close掉
 9.執行緒也是造成記憶體洩露的一個重要的源頭。執行緒產生記憶體洩露的主要原因在於執行緒生命週期的不可控
 10.如果ImageView的圖片是來自網路,進行非同步載入
 11.應用開發中自定義View的時候,互動部分,千萬不要寫成執行緒不斷重新整理介面顯示,而是根據TouchListener事件主動觸發介面的

  三、AndroidUI優化
1.layout元件化,儘量使用merge及include複用
2.使用styles,複用樣式定義
3.軟鍵盤的彈出控制,不要讓其覆蓋輸入框
4.數字、字母和漢字混排佔位問題:將數字和字母全形化。由於現在大多數情況下我們的輸入都是半形,所以 字母和數字的佔位無法確定,但是一旦全形化之後,數字、字母的佔位就和一個漢字的佔位相同了,這樣就可以避免由於佔位導致的排版問題。
5.英文文件排版:textview自動換行時要保持單詞的完整性,解決方案是計算字串長度,然後手動設定每一行顯示多少個字母並加上‘n‘
6.複雜佈局使用RelativeLayout
7.自適應螢幕,使用dp替代pix
8.使用android:layout_weight或者TableLayout製作等分佈局
9.使用animation-list製作動畫效果
---------------------------------------------------------------------------------------
>>>>>>>>>>命名規範這種東西每個人都有自己的風格,Google 也有自己的一套規範(多看看 Android 系統原始碼就明白了)。

  1.好的規範可以有效地提高程式碼的可讀性,對於將來接手程式碼的小夥伴也是一件幸事。題主可以自行 Google 一下 Java (Android)命名規範,會由不少的部落格介紹。其次是註釋。嚴格來說這個應該屬於命名規範的範疇。註釋一方面是幫助自己記憶 ,另一方面是團隊協作中的一個規範,特別是對於開發 API 的小夥伴來說,總不能天天被人跟在屁股後面問你這個介面是什麼作用,你這引數是什麼意思?好的註釋配合好的命名規範,可以省去很多溝通上的成本。
  2.註釋至少要有如下幾方面的內容:該介面(或類)的作用。注意寫的應該是作用,而不是你做了什麼;引數列表的各個引數說明;返回值的說明;如果有異常丟擲,對丟擲異常的說明;如果註釋是在類上的,總得留個聯絡方式吧,免得以後出了問題都找不到原作者。當然了,如果類設計的過於讓人蛋疼,我也可以聯絡到作者,約出來,打一頓的嘛。其他你認為有必要解釋。
  3.再者是版本控制。就算是自己一個人寫程式碼,版本控制也是有必要的。Git 也好,SVN 也好,都是有幫助的。版本控制一方面是對自己程式碼的一個備份,另一方面,如果想回滾到歷史版本也是極有幫助的。所以最好能夠熟悉一下 Git 或者 SVN 的使用。
  第四是名詞表。這個應該屬於肥肥自創。Android 是圍繞四大元件特別是 Activity 和 Service 進行開發的,但是如果專案龐大,有多個 Activity 存在,那麼記住每一個 Activity 的類名是很難得,但是記住每一個 Activity 的功能卻相對容易。故而肥肥在帶專案的過程中自創了名詞表這一東東。記錄了每一個模組、元件、甚至是每一個 Activity 的官方統一名稱(比如,功能是作品列表的 Activity,名稱就叫作品列表頁,對應的類是 WorksListActivity),在溝通過程中,大家(包括測試人員等專案相關人員)統一說“作品列表頁”。當時的初衷是解決測試團隊的Bug 描述過於模糊(如果有多個列表頁,測試人員往往會寫列表頁****問題)。
  第五是不要重複製造輪子。這個適用於程式碼層面以及業務層面。
  第六是千萬不要餓著肚子寫程式碼。先挖這個坑,吃了東西再找時間繼續寫。
  第七這一點應該不算是習慣,但是卻需要每一個 Android 程式猿需要慎重再者慎重的地方---記憶體管理。Android 雖然延續了 Java 的垃圾回收機制,但是並不意味 Android 應用程式就不會出現記憶體問題。在 Android 中引起記憶體開銷過大的往往是 BitMap 物件。BitMap.java實際上是 Skia 引擎中對圖片處理部分的 Java 層程式碼而已(真正工作的是 C++層程式碼,通過 JNI 封裝,最後提供 Java 層的介面),那麼你建立 BitMap 物件實際上是建立了兩部分記憶體,一部分是 Java 層的,就是  BitMap物件,Java 的垃圾回收會在合適的時機回收這一部分記憶體。另一部分是 C++層面的,也就是通過 JNI 呼叫 C++層的程式碼分配的那一部分記憶體。Java 的垃圾回收是不會回收這一部分記憶體的,所以如果不手動釋放的話就容易引起記憶體問題。
  第八是千萬不要阻塞使用者主執行緒。使用者主執行緒就是 UI 執行緒,主要負責 UI 的繪製(除 SurfaceView 外,其他 View 物件都是需要在 UI 執行緒中程式操作的)。為了保證 App 的互動儘可能的流程,請不要在 UI 執行緒中進行耗時操作(檔案讀寫、Http 請求(4.0之前可以在主執行緒中發起)等)。否則會引起兩種可能的問題:第一是造成使用者互動極度不流暢,第二容易觸發 ANR 的超時機制(UI 執行緒5秒,廣播10秒)。
  第九是嚴格把控生命週期(Activity、Service、ContentProvider 等)。在每一個生命週期事件中,明確應該做什麼不應該做什麼是很有必要的,不然也會容易造成各種莫名其妙的問題(比如 onCreate 中使用了 onResume 中才初始化的物件)。
  第十是在使用 XML 檔案進行 UI 佈局時,應該儘量減少 Layout 的巢狀層級。Layout 的過度巢狀會造成渲染時資源開銷過大的問題。寫到這裡突然不想寫了。
  第十一應該是資原始檔的使用,資原始檔包括圖片、字串、尺寸、顏色等等。在使用尺寸資源的時候應該儘量使用畫素無關的單位,比如 dp 和 sp。而字串資源(比如 Button 上顯示的名稱)也應該儘可能的抽離出來,使用 res/value 下的xml 檔案進行維護。一方面方便日後管理,另一方面方便國際化。
  第十二多執行緒以及執行緒池的使用。前面說過應該儘量避免在主執行緒中執行耗時操作,那麼多執行緒就變得很有必要。對於 Java 來說,執行緒的建立與銷燬是非常佔用資源的,執行緒的濫用(隨手 new Thread 等)會造成 App 整體效能的下降。Java 提供了Executors的執行緒池方案,而 Android 自身也提供了AsyncTask 這樣的非同步任務方案(實際上也是執行緒池)。
  第十三 Java 的許可權控制機制。Java提供了public, private, protected 三個訪問許可權修飾詞,提供了以下四種訪問許可權控制機制:包訪問許可權;Public訪問許可權;Private訪問許可權;Protected訪問許可權;訪問許可權的合理使用可以有效地隱藏實現,避免將不必要的資料或介面暴露出來。
  第十四 final 和 static 關鍵字的合理使用。很多人覺得這是很基礎的東西,但是 final 和 static 關鍵字的合理使用能夠有效提升程式碼的執行效率,而不合理使用則後患無窮。
  第十五 Android 裝置的記憶體資源是極度珍貴的,合理的使用、回收記憶體也是一種好的程式設計習慣。Java 物件的引用型別會影響到垃圾回收物件的時機。Java 有強引用、 軟引用、 弱引用、虛引用,以及 Android 增加的 Lru 記憶體管理。建議題主瞭解一下這四種引用型別的特點以及 Lru 記憶體管理的具體實現。
  第十六 介面和抽象類。這是老生常談的話題了,但卻是永恆的話題。介面和抽象類的合理使用,可以增加程式碼的可維護性和擴充套件性。介面和抽象類也是各種設計模式的基石。
  第十七 軟體設計的六大設計原則,即針對介面程式設計,不針對實現程式設計單一職責原則開放封閉原則里氏代換原則迪米特法則合成聚合複用原則
  第十八 統一專案的編碼格式(推薦使用 UTF-8)。如果多人協作,這種舉措顯得尤為重要。由此引申出來的另外一個規範就是,規範統一命名風格,即團隊中使用相同的命名風格。(感謝@徐強 的提醒。更新於2014年12月30日17:22:20)
  第十九 TextView(往往 TextView 派生子類同樣適用)呼叫 setText 方法設定一個 int 型的資料,千萬要將該值轉為 String,否則在某些裝置中它會預設去查詢 R 檔案中定義的資源.
  第二十 使用友盟分享 SDK,需要執行分享的 Activity 請不要為該 Activity 設定android:process屬性。比如你的 App 執行在 com.codingfish.test 程式,需要產生分享動作的Activity 設定 android:proces=":com.codingfish.hello" ,那麼新浪微博就會出現你設定的分享內容沒有顯示的問題。該 Bug 已經提交給友盟的技術人員,但是 N 久沒有得到修復。
  第二十一 上線之前一定要使用正式簽名打包。某朋友公司 Android 的應用上架之前,負責打包上線的童鞋(新人,老人已離職,只有這一個Android)沒有簽名的概念,直接將 Debug 簽名的 Apk 投放到渠道了,到現在還有一批裝置沒有替換回來。
  第二十二 在 Activity 中儘可能少的建立 Handler 物件,建立一個主執行緒 Handler,一個後臺 HandlerThread 就可以了。
  第二十三 使用執行緒的地方儘量不要 new Thread,而是使用 AsyncThread 。
  第二十四 onCreate(Bundle savedInstanceState)  切記將super.onCreate(savedInstanceState);放在一切業務的前面。
  第二十五 建立了四大元件一定記得要在 AndroidManifest 檔案中宣告(當然 BroadcastReceiver 可以動態註冊)。
  第二十六 為Activity宣告系統配置變更事件  系統配置變更事件是指轉屏,區域語言發生變化,螢幕尺寸發生變化等等,如果Activity沒有宣告處理這些事件,發生事件時,系統會把Activity殺掉然後重啟,並嘗試恢復狀態,Activity有機會通過onSaveInstanceState()儲存一些基本資料到Bundle中,然後此Bundle會在Activity的onCreate()中傳遞過去。雖然這貌似正常,但是這會引發問題,因為很多其他的東西比如Dialog等是要依賴於具體Activity例項的。所以這種系統預設行為通常都不是我們想要的。為了避免這些系統預設行為,就需要為Activity宣告這些配置,如下二個是每個Activity必須宣告的:<activity android:configChanges="orientation|keyboardHidden">幾乎所有的Activity都要宣告如上,為什麼Android不把它們變成Default的呢?
  第二十七  儘量使用Android的API 這好像是廢話,在Android上面開發不用Android API用什麼?因為Android幾乎支援Java SE所有的API,所以有很多地方Android API與Java SE的API會有重複的地方,比如說對於檔案的操作最好使用Android裡面Context封裝的API,而不要直接使用File物件:Context.openFileOutput(String); // no File file = new File(String)原因就是API裡面會考慮到Android平臺本身的特性;再如,少用Thread,而多使用AsyncTask等。
  第二十八  要考慮到Activity和程式被殺掉的情況  如了通常情況退出Activity外,還有Activity因其他原因被殺的情況,比如系統記憶體過低,系統配置變更,有異常等等,要考慮和測試這種情況,特別是Activity處理重要的資料時,做好的資料的儲存。
  第二十九  小心多語言  有些語言真的很囉嗦,中文或英文很簡短就能表達的事情到了其他語言就變的死長死長的,所以如果是wrap_content就可能把其他控制擠出可視範圍; 如果是指定長度就可能顯示不全。也要注意特殊語言比如那些從右向左讀的語言。
  第三十  不要用四大元件去實現介面  一是元件的物件都比較大,實現介面比較浪費,而且讓程式碼更不易讀和理解; 另外更重要的是導致多方引用,可能會引發記憶體洩露。
  第三十二 用getApplication()來取Context當引數 對於需要使用Context物件作為引數的函式,要使用getApplication()獲取Context物件當引數,而不要使用this,除非你需要特定的元件例項!getApplication()返回的Context是屬於Application的,它會在整個應用的生命週期記憶體在,遠大於某個元件的生命週期,所以即使某個引用長期持有Context物件也不會引發記憶體洩露。
  第三十三 主執行緒只做UI控制和Frameworks回撥相關的事。附屬執行緒只做費時的後臺操作。互動只通過Handler。這樣就可以避免大量的執行緒問題。
  第三十四 Frameworks的回撥不要做太多事情僅做必要的初始化,其他不是很重要的事情可以放到其他執行緒中去做,或者用Handler Schedule到稍後再做。
  第三十五  要考慮多解析度  至少為hdpi, mdpi, ldpi準備圖片和佈局。元素的單位也儘可能的使用dip而不要用px。
  第三十六  利用Android手機的硬鍵  幾乎所有的Android手機都有BACK和MENU,它們的作用是返回和彈出選單,所以就不要再在UI中設計返回按扭和選單按扭。很多優秀的應用如隨手記和微信都有返回鍵,他們之所以有是因為他們都是從iOS上移植過來的,為了儲存體驗的一致,所以也有了返回和選單。但這不夠Android化,一個純正的Android是沒有必須重複硬鍵的功能的。PS:多看看官方的 APIDEMO,多讀一下Android 上的內容。肥肥上面的各種廢話,題主基本都能在開發者官網找到。
  第三十七 最好的一個習慣,放到最後壓軸吧。善用 Google 和知乎。

--------------------------------------------

> 高效地利用執行緒我們知道App執行過程中所有的操作都預設在主執行緒(UI執行緒)中進行的,這樣App的響應速度就會受到影響。會導致程式陷入卡頓、死掉甚至會發生系統錯誤。為了加快響應速度,需要把費時的操作(比如網路請求、資料庫操作或者複雜的計算)從主執行緒移動到一個單獨的執行緒中。最高效的方式就是在類這一級完成這項操作,可以使用AsyncTask或者IntentService來建立後臺操作。如果選擇使用IntentService,它會在需要的時候啟動起來,然後通過一個工作執行緒來處理請求(Intent)。

>>>>>>>使用IntentService時需要注意以下幾點限制:
  1.這個類不要給UI傳遞資訊,如果要向使用者展示處理結果資訊請用Activity;每次只能處理一個請求;每一個處理請求過程都不能中斷;
  2、保持響應不發生ANR從UI執行緒中移除費時操作這個方式還可以防止使用者操作出現系統不響應(ANR)對話方塊。需要做的就是繼承AsyncTask來建立一個後臺工作執行緒,並實現doInBackground()方法。還有一種方式就是自己建立一個Thread類或者HandlerThread類。需要注意這樣也會使App變慢,因為預設的執行緒優先順序和主執行緒的優先順序是一樣的,除非你明確設定執行緒的優先順序。
  3、線上程中初始化查詢操作當查詢操作正在後臺處理時,展示資料也不是即時的,但是你可以使用CursorLoader物件來加快速度,這個操作可以使Activity和使用者之間的互動不受影響。使用這個物件後,你的App會為ContentProvider初始化一個獨立的後臺執行緒進行查詢,當查詢結束後就會給呼叫查詢的Activity返回結果。
  4、需要注意的方面使用StrictMode來檢查UI執行緒中可能潛在的費時操作;使用一些特殊的工具如Systrace或者Traceview來尋找在你的應用中的瓶頸;用進度條向使用者展示操作進度;如果初始化操作很費時,請展示一個歡迎介面。優化裝置的電池壽命。如果應用很費電,請不要責怪使用者解除安裝了你的應用。對於電池使用來說,主要費電情況如下:更新資料時經常喚醒程式;用EDGE或者3G來傳遞資料;文字資料轉換,進行非JIT正規表示式操作。
  5、優化網路如果沒有網路連線,請讓你的應用跳過網路操作;只在有網路連線並且無漫遊的情況下更新資料;選擇相容的資料格式,把含有文字資料和二進位制資料的請求全部轉化成二進位制資料格式請求;使用高效的轉換工具,多考慮使用流式轉換工具,少用樹形的轉換工具;為了更快的使用者體驗,請減少重複訪問伺服器的操作;如果可以的話,請使用framework的GZIP庫來壓縮文字資料以高效使用CPU資源。
  6、優化應用在前端的工作如果考慮使用wakelocks,儘量設定為最小的級別;為了防止潛在的bug導致的電量消耗,請明確指定超時時間;啟用 android:keepScreenOn屬性;除了系統的GC操作,多考慮手動回收Java物件,比如XmlPullParserFactory和BitmapFactory。還有正規表示式的Matcher.reset(newString)操作、StringBuilder.setLength(0)操作;要注意同步的問題,儘管在主執行緒中是安全的;在Listview中要多采用重複利用策略;如果允許的話多使用粗略的網路定位而不用GPS,對比一下GPS需要1mAh(25s * 140 mA),而一般網路只用0.1mAh(2s * 180mA);確保登出GPS的位置更新操作,因為這個更新操作在onPause()中也是會繼續的。當所有的應用都登出了這個操作,使用者可以在系統設定中重新啟用GPS而不浪費電量;請考慮在大量數理運算中使用低精度變數並在用DisplayMetrics進行DPI任務時快取變數值;
  7、優化工作在前臺的應用請確保service生命週期都是短暫的,因為每個程式都需要2MB的記憶體,而在前臺程式需要記憶體時也會重新啟動;保持記憶體的使用量不要太大;如果要應用每30分鐘更新一次,請在裝置處於喚醒狀態下進行;Service在pull或者sleep狀態都是不好的,這就是為什麼在服務結束時要使用AlarmManager或者配置屬性stopSelf()的原因。
  8、電池其它注意事項在進行整體更新之前檢查電池的狀態和網路狀態,等待最好的狀態再進行大幅度裝換操作;讓使用者看到用電情況,比如更新週期,後臺操作的時候;
  9、怎麼找到佈局顯示問題當我們為佈局單獨建立UI的時候,就是在建立濫用記憶體的App,它在UI中會出現可惡的延時。要實現一個流暢的、低記憶體佔用的UI,第一步就是搜尋你的應用找出潛在的瓶頸佈局。使用Android SDK/tools/中自帶的Hierarchy Viewer Tool工具。還有一個很好的工具就是Lint,它會掃描應用的原始碼去尋找可能存在的bug,併為控制元件結果進行優化。

  10、解決問題如果佈局顯示結果發現了問題,你可以考慮簡化佈局結構。可以把LinearLayout型別轉化成RelativeLayout型別,降低佈局的層級結構。

------------------------------------------------------------------------------------------------------------------------------------------------
  
  1、四大元件以及Fragment的生命週期如果只要寫一個能用的APP的話,知道生命週期的流程就夠用了。不過我建議還是要詳細閱讀原始碼(不一定要全部懂),知道Android系統後臺管理元件的什麼週期的大概流程,理解Android系統元件生命週期設計的意圖,瞭解這些關鍵字:ActivityManager,FragmentManager,WindowManager。
  2、 知道生命週期後Android系統記憶體空間不夠後,會回收相應生命週期內的元件,所以你應該保證的你Activity在onStop或者OnDestroy後,沒有被其他物件引用著,不然會造成系統無法回收記憶體空間,這樣就造成記憶體洩露了,結果要麼是系統變卡,要麼直接拋OOM Error。
  3、所以應該遵循元件的生命週期,儲存和恢復資料(嗎)Android元件的什麼週期應該是系統控制的,APP不能干預,APP要做的是在Activity銷燬時儲存資料,建立或恢復時恢復資料。但是為了不讓Activity每次重新建立的時候都重新去拉取資料浪費流量,要在onsaveinstancestate的時候把資料儲存, onrestoreinstancestate的時候把資料恢復嗎?不全是,用Intent傳遞資料時,容量是有限制的,應該儘量儲存一些關鍵的引數用於恢復資料(例如Adapter的當前position,最好是基本的Parcelable型別),如果資料太大會拋TransactionTooLargeException,如果真的想儲存大資料的話推薦用序列化物件儲存。
  4、不要輕易new Thread().start();為了保證主執行緒(Activity Thread)的順暢,應該把一些耗時的工作都放到後臺執行緒去,但是也不要輕易地建立執行緒,因為執行緒啟動後我們就很能控制它了,如果執行緒引用著Activity的例項的話那更糟糕,會容易造成Activity無法被回收,而Activity又引用著大量的資源(所以系統記憶體空間不夠用的時候最喜歡回收Activity),容易造成OOM,這也是一個專案越大越容易出現卡頓的問題之一。
  5、應該控制好整個專案中Thread的數量不要輕易new Thread().start();,採用類似Looper的迴圈佇列,需要後臺工作的使用,用對應的Looper的Handler把任務提交到Looper的佇列裡執行,我自己控制的執行緒數大概有:ActivityThreadHttpTheadImageLoader ThreadFileThreadSqliteThreadLogThread (其實可以用FileThread,但是我把LOG的檔案儲存給單獨拿出來了)……每次要做長時間的任務時,都是把任務扔到現有的佇列中,而不是new Thread()
  6、不推薦使用AsyncTask和Timer,用Handler代替AsyncTask用來做非同步任務確實比自己寫Thread方便許多,問題是AsyncTask自己內部維護了一個執行緒池,執行緒的數目不好控制(可以自定義),而且AsyncTask同樣容易引用著Activity導致資源沒被回收,Timer同理。

相關文章