引用:http://my.eoe.cn/blue_rain/archive/3631.htmlhtml
每一個模式都描述了一個在咱們的環境中不斷出現的問題,而後描述了該問題的解決方案的核心。經過這種方式,你能夠無數次地使用那些已有的解決方案,無需在重複相同的工做。設計模式
設計模式是在某種特別的狀況下,針對某種問題的某種典型、通用的解決方法。緩存
咱們是須要適當瞭解並學習一些設計模式,在程序開發過程當中,老是會涉及到一些框架設計,模塊設計之類的東西,若是能很好理解並運行設計模式,你所設計的模塊或框架將會要穩定得多,由於這些設計模式它們都是通用的解決方案,是通過實踐經驗了的。網絡
好比說,在程序裏,可能會有通知模塊,A模塊的數據發生變化,B模塊須要獲得通知,對於這樣的須要,你可能會想到用"廣播","消息"或者"回調"的方式來解決,的確,剛纔我所說的那三種也能解決,可是,這三種都是存在一些缺點,好比說廣播,用Intent來傳輸數據很困難,對於"消息",沒法很好的跟蹤,對於"回調",有可能你A與B模塊根本不可相互訪問。此時,若是你會用觀察者模式的問題,這種問題能夠很輕鬆解決。架構
固然,這裏是須要具體問題具體分析的,我主要的意思就是說,要適當利用模式,咱們不能爲了用模式而去用模式,咱們是要用模式來解決咱們實際的問題。app
關於概念完整性,在《人月神話》一書在有大量的闡述,這裏,我把個人理解寫出來,與你們分享。框架
1)概念完整性是系統設計中最重要的考慮因素。當你的系統規模越大,這一點體現得越明顯。異步
2)爲了獲取概念的完整性,設計必須由一我的或者具備共識的小型團隊來完成。這一點很好理解,關於設計,可讓全部的人蔘與,可是決定權在少數人手裏,若是你們都想參與設計,這是根本沒有辦法保正系統設計是統一完整的。ide
3)要得到概念上的完整性,就必須有人控制這些概念,相似於貴族的專制統治。這裏,對於團隊中的項目經理或架構師必須對項目有絕對的權威,否則,這個項目裏面的就沒法統一號令。oop
4)概念完整性表現有:
1 2 3 4 5 |
- 開發過程當中,需求、設計、編碼的一致性
- 整個程序具備統一的風格,好比對話框樣式,按鈕風格,色調等UI元素
- 整個程序具體統一的結構,好比不一樣模塊訪問網絡,它們的調用方式一致,例如異步訪問都用回調方式通知結果,相同的功能應該提取成共通模塊。
- 開發人員能很好的執行需求人員和設計人員的意圖。
- 有完整的文檔,需求文檔,設計文檔,測試文檔,處理流程的文檔等。
|
1 2 3 4 5 |
- 在制度上給予保證,產品的負責人必須創建技術上的絕對權威
- 技術負責人員(SE,SL)必須嚴格執行項目的需求,設計,必須深刻到編碼細節
- 在不一樣階段,保持與全部人員的持續溝通,鼓勵開發人員提意見。
- 讓開發人員參與設計,但不決定設計
- 經過持續的反饋和溝通來實現模塊重用
|
TextView
EditText
Button
Title bar
Tool bar
...
### 爲何要提供這些共通控件? ###
統一字體大小,如App字體不隨系統字體變化而變化
統一UI式樣,如Button, EditText具備相同的背景等
複用代碼
根據式樣,提取須要在AdapterView中顯示的Item
簡單的複合佈局
自繪製,從而提升滑動性能
- ListView中放Gallery時,提升上下滑動性能
- 儘可能優化繪製
### 數據驅動 ###
Adapter Items提供核心的方法
- setData(Object data)
- getData();
Adapter#getView實現更加簡單
- 實現簡單
- 不會由於UI變化而變化
下面代碼示例了Adapter#getView()方法的實現,它返回BookView,BookView提供方法來接收數據,至於BookView的顯示,則根據設置的數據來顯示,這就是數據驅動UI。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
convertView = new BookView(getContext());
convertView.setLayoutParameter(new AbsListView.LayoutParameter(150, 150));
}
Book book = m_bookList.get(position);
BookView bookView = (BookView)convertView;
bookView.setBook(book);
return convertView;
}
|
擴展於Dialog類
提供Dialog關閉的事件
Dialog的高度隨內容的變化而變化
能夠設置按鈕的文字,可見性,字體等方法
設置按鈕點擊事件的listener
要考慮對話框的三個屬性:Title, Content area, Action buttons
-Log
DateFormat
Bitmap
Notification
Shared Preference
Environment
Device
...
線程只是一種機制,保證咱們要完成的任務不運行在UI線程(也就是說不阻塞UI),完成的任務纔是咱們關注的核心,所以,咱們能夠經過設計,把線程封裝,讓使用者根本感受不到是線程,他只用關心他要作的事情就好了。
這裏,咱們能夠設計一種"異步鏈式調用"的框架,把線程進行了封裝。使用都只須要這樣用:
1 2 3 4 5 |
new TaskManager()
.next(task1)
.next(task2)
.next(task3).
.execute();
|
這裏,task1, task2, task3是順序執行的,舉個例子:咱們要訪問網絡,取得一個圖片,使用這個TaskManager咱們須要3個task,
task1:顯示一個ProgressDialog。
task2:訪問網絡,建立bitmap。
task3:關閉對話框,顯示bitmap。
這一點,能夠參考CoreLib工程中的task.TaskManager類。
關於TaskManager,有如下幾點須要注意:
-封裝了線程
讓調用者只關注本身的業務處理
保證順序鏈式地執行某一個任務
上一個任務的輸出,做爲下一個任務的輸入
能暫停、恢復任何一個任務
-把內存佔用量大的對象存放在緩存中,如bitmap
利用了LruCache類來實現
利用了AsyncTask類來加載bitmap
不用再手動釋放bitmap內存,該操做有風險
不用再關心AbsListView的scroll狀態
關於緩存的更多詳細細節,請參考[ 請參考CoreLib工程中的cache包 ]。
這樣作,有什麼好處, 不用再手動釋放bitmap內在,該操做有風險,由於該bitmap是否有View引用,若是當一個View在試圖繪製一個已經回收的bitmap,這裏會拋出異常。
1 2 3 4 5 6 |
new Thread(null, new Runnable() {
public void run() {
// Do you works.
}
}, "Thread_name_xxx").start();
|
什麼狀況下使用這種線程:
-作完一件事情就結束,這件事發生頻率不高,好比從SD card中讀取圖片數據
不須要複用線程
在使用線程,最好給線程加上名字,這樣利用高度與跟蹤。
這樣的線程擁有消息循環,當消息隊列中沒有消息時,這個線程會被掛起。咱們要作一件事情時,只須要給它發送一個消息就好了。
這種狀況一般是爲了複用線程,不用頻繁建立線程,好比音樂播放器程序,專門啓動一個有消息循環的線程來得到音樂的專輯圖片。
咱們一般還要建立一個與這個線程的消息循環(Looper)相關聯的Handler,由它來處理消息,注意,這作的事情是運行在後臺線程的。
UI層
數據展現與管理
用戶交互
繪製
Adapter
業務邏輯層
持久化數據(內存中,至關於全局數據)
數據加式(數據層的數據有時候須要進行加工成UI層須要的數據)
數據變化的通知機制
數據層
數據訪問(DB,文件,網絡等)
緩存(圖片,文件等)
配置文件(shared perference)
下面,我試着畫了一個Android程序的結構,若是有很差的地方,歡迎指正。
下面列出一些一般的原則,咱們應當在開發過程當中遵循,歡迎補充與指正。
在Activity.onCreate()或者View的構造方法中調用,在之後看代碼時,人們一般首先會去找initialize()這樣的方法。
把View的點擊事件,提成方法,這樣在listener處只是一個方法調用者,通常的事件封裝爲:onXXXClick(View v)。
讓全部的Activity都繼承自BaseActivity類,這樣,咱們能夠作不少有用的事情
-定義共通屬性
顯示共通對話框(Progress dialog)
取得top activity
能夠手動管理啓動的activity
存全局數據,比top activity, application context。
-報告功能是處理異常的精髓
在finally塊中執行清理操做
不要用try-catch-finally來判斷業務邏輯
考慮設計自定義的異常類
-重寫的方法必定要加@Override
不使用的方法,不要刪除,能夠標記爲@Deprecated,這個作法在維護型的項目中特別有用。
-局部廣播
各類listener
Service等
咱們應當把Bitmap操做封裝起來,好比從文件加載,保存,網絡下載,動態計算sample size等。有了封裝後,咱們能夠對其集中優化。
必定要注意繪製方面的東西,不要在onDraw()/onTouchEvent()中建立新對象。