編輯:關於Android編程
性能提升
有兩個編寫有效代碼的基本規則:
1:不要做你不需要做的。
2:不分配沒必要分配的內存。
應該盡量避免創建多余的對象,比如:
1:在一組輸入數據中抽取字符串時,嘗試返回源數據的子串,而非創建一個副本
2:如果你有一個返回String的方法,而且你知道它的結果將會一直被追加到StringBuffer,改變你的簽名和實現,在這個函數裡面直接追加,避免創建臨時對象。
3:將多維數組切成與之平行的一維數組
4:一個int數組比Integer數組要好,一個公認的事實就是兩個平行的int數組要比一個(int,int)對象數組要高效很多。對於其它原始數據類型亦如是
應該盡量使用Native方法 ,比如:
當處理字符串時,要毫不猶豫地使用諸如String.indexOf()、String.lastIndexOf()之類的專門方法,這些是典型的用C/C++代碼實現的方法,它們可以輕易地比實現同樣功能的Java循環快10-100倍
優先使用實現類,而不是接口
對於嵌入式系統來說,通過接口的引用來調用一個方法要比通過一個具體類型的引用調用virtual方法花多2倍的時間。
但是公共API除外,好的API較少考慮性能。
優先選擇static而非virtual
如果你不必訪問一個對象的字段,使你的方法成為static方法。它可以被更快地調用,因為它不需要一個虛擬方法來間接調用。
避免內部的Getter/Setter
在Android,虛擬方法調用代價是昂貴的,實例字段查找代價更高。沿用一般面向對象編程實踐在公開接口中提供gettter和setter是合理的,但在一個類中你應該直接訪問字段 。
訪問對象字段要比訪問本地變量慢得多,如下面這段:
java代碼:
查看復制到剪貼板打印
for (int i = 0; i < this.mCount; i++)
dumpItem(this.mItems[i]);
應該寫成這樣:
int count = this.mCount;
Item[] items = this.mItems;
for (int i = 0; i < count; i++)
dumpItems(items[i]);
(我們用一個顯式的"this"來表明這是一個成員變量。)
同樣的,不要在for語句中的第二個從句中調用方法。例如下面這段代碼將會在每次迭代中都會執行一次getCount(),這是一個巨大的浪費,你可以將它的值cache為一個int。
java代碼:
查看復制到剪貼板打印
for (int i = 0; i < this.getCount(); i++)
dumpItems(this.getItem(i));
緩存查詢字段 , 通常,如果你將要訪問一個實例字段多次,一個好的習慣就是創建一個臨時變量。例如:
java代碼:
查看復制到剪貼板打印
protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) {
if (isHorizontalScrollBarEnabled()) {
int size = mScrollBar.getSize(false);
if (size <= 0) {
size = mScrollBarSize;
}
mScrollBar.setBounds(0, height - size, width, height);
mScrollBar.setParams( computeHorizontalScrollRange(),
computeHorizontalScrollOffset(),
computeHorizontalScrollExtent(), false);
mScrollBar.draw(canvas);
}
}
這是對成員字段mScrollBar的四次分開查找,通過將mScrollBar緩存到本地變量,四次成員字段查找變成四次本地變量引用,這樣更為高效。
同樣地,方法參數作為本地變量擁有相同的性能特征。
聲明常量為static final,主要是針對屬性字段,你也可以將本地變量聲明為final,然而這並無真正意義上的性能提升 。
使用增強的For循環語句
增強的For語句對於數組表現良好,但對iterable對象要小心使用,因為有額外的對象創建。對於ArrayList,你最好直接遍歷它,但對於其它collections,增強的For循環語句將會等同於顯式的迭代用法。
避免使用Enum類型
避免使用Float類型
嵌入式處理器很少具有硬件浮點支持,所以所有的“float”和“double”操作都是在軟件上進行。某些基本的浮點操作可能會花費數微秒。
避免使用JNI
支持多種屏幕
在實際開發中,由於由於不同手機的尺寸大小,屏幕分辨率可能存在差異,這會帶來很多的問題,比如:
1:圖片在不同的設備上,大小顯示不一
2:Layout在不同的設備上,顯示不一樣,可能變形了
一些基本的解決方法:
1:對於字體,盡量使用sp作為單位,其他的盡量使用dp或者dip
2:使用wrap_content, fill_parent, 或者 dp 來定義layout的尺寸大小
3:不同密度設備對應圖像文件的最佳比例。
對於四種密度low-dpi, medium-dpi, high-dpi, extra high-hdpi的設備,在指定一個相同的圖像文件時,分配給各種密度的圖像文件的尺寸應該符合以下比例:3:4:6:9. 也就是要符合密度比例(120:160:240:360)。
舉個列子,假如我們要在一個密度為160dpi的設備上使用到一個48 * 48的圖像文件。那麼對於其它密度的設備,我們要准備的圖像文件分別是:
low-density (120dpi) : 36×36
medium-density(160dpi): 48×48
high-density (240dpi) : 72×72
high-density (360dpi): 96×96
4:在需要的情況下,為每種尺寸的設備提供指定的layout文件。
5:在需要的情況下,為每種密度的設備提供不同的圖像文件
6:不使用absoluteLayout布局
UI最佳實踐
這是一份來自Moto的,關於Android UI的最佳實踐,要點如下:
1:閱讀UI指導方針(UI guideline)
2:理解和設計觸摸模式
3:支持多種交互模式 (如鍵盤、軌跡球、觸摸屏等)
4:使用通知(notifications)和窗口陰影(window shade)
5:支持應用間的交互
6:保持你的用戶界操作面快速且敏感
7:使用窗體部件和文件夾
8:運用屏幕方向的改變
9:巧用圖片
10:使用適用於多設備的布局
這是一份來自Android官方開發者博客,關於Android UI的最佳實踐
不應該
1.不要照搬你在其它平台的UI設計,應該讓用戶感覺是在真正使用一個 Android 軟件,在你的商標顯示和平台整體觀感之間做好平衡
2.不要過度使用模態對話框
3.不要使用固定的絕對定位的布局
4.不要使用px單位,使用dp或者為文本使用sp
5. 不要使用太小的字體
應該
1. 為高分辨率的屏幕創建資源(縮小總比放大好)
2. 需要點擊的元素要夠大
3. 圖標設計遵循 Android 的准則
4. 使用適當的間距(margins, padding)
5. 支持D-pad和trackball導航
6. 正確管理活動(activity)堆棧
7. 正確處理屏幕方向變化
8. 使用主題/樣式,尺寸和顏色資源來減少多余的值
9.和視覺交互設計師合作!!!
設計哲學
1. 干淨而不過於簡單
2. 關注內容而非修飾
3. 保存一致,讓用戶容易投入其中,可附加少許變化
4. 使用雲端服務(存儲和同步用戶資料)來加強用戶體驗
優秀界面的設計准則
1. 關注用戶
2. 顯示正確的內容
3. 給予用戶適當的回饋
4. 有章可循的行為模式
5. 容忍錯誤
關注用戶
1. 了解你的用戶(年齡,技能,文化,對你的應用的需求,使用的設備,何時何地如何使用設備)
2. ‘用戶優先’的設計心態 (用戶通常是任務導向的行為模式)
3. 更早,更頻繁的由真實用戶來測試
顯示正確的內容
1. 最常用的操作需要最快被用戶看到並且可用
2. 不太常用的功能可以放到菜單裡面
給予用戶適當的回饋
1. 交互式的UI元素最少需要反映出4種不同的狀態 (default,disabled,focused,pressed)
2. 保證操作的結果是清晰可見的
3. 多給予用戶進度提示,但是不要干擾他們當前的操作
有章可循的行為模式
1. 行為模式遵循用戶的期望(正確的操作活動堆棧,顯示用戶期望看到的信息和動作)
2. 使用合適的方式來加強功能可見性(可點擊的元素就應該看起來是可以點擊的)
3. 如果用戶完成一項任務需要復雜的操作,重新思考你的設計!!!
容忍錯誤
1. 只允許有意義的操作(適當禁用一些按鈕)
2. 盡量減少不可回退的操作
3. 允許回退(undo)比使用確定對話框更好(實際上,應該盡量少用確定對話框,它對用戶是一種干擾)如果錯誤是可能發生的,那它就一定會發生。
設計的考量
1.屏幕的物理尺寸
2.屏幕密度
3. 屏幕的方向(豎向和橫向)
4.主要的UI交互方式(觸屏還是使用D-pad/trackball)
5.軟鍵盤還是物理鍵盤
6.了解不同設備之間的相異之處是非常重要的!
7.閱讀CDD,學習設備可能差異的地方
8.了解屏幕尺寸和密度分類
響應的靈敏性(Designing for Responsiveness)
應用程序響應不夠靈敏的地方包括——反映遲鈍,掛起或凍結很長時間,或者需要花費很長的時間來處理輸入。
在 Android上,如果你的應用程序有一段時間響應不夠靈敏,系統會向用戶顯示一個對話框,這個對話框稱作應用程序無響應 (ANR:Application Not Responding)對話框。
什麼引發了ANR:在Android裡,應用程序的響應性是由Activity Manager和Window Manager系統服務監視的。當它監測到以下情況中的一個時,Android就會針對特定的應用程序顯示ANR:
1:在5秒內沒有響應輸入的事件(例如,按鍵按下,屏幕觸摸)
2:BroadcastReceiver在10秒內沒有執行完畢
如何避免ANR
運行在主線程裡的任何方法都盡可能少做事情。特別是,Activity應該在它的關鍵生命周期方法(如onCreate()和onResume()) 裡盡可能少的去做創建操作。潛在的耗時操作,例如網絡或數據庫操作,或者高耗時的計算如改變位圖尺寸,應該在子線程裡(或者以數據庫操作為例,通過異步請 求的方式)來完成。
增強響應靈敏性
一般來說,在應用程序裡,100到200ms是用戶能感知阻滯的時間阈值。這裡有一些額外的技巧來避免ANR,並有助於讓你的應用程序看起來有響應性。
1:如果你的應用程序為響應用戶輸入正在後台工作的話,可以顯示工作的進度(ProgressBar和ProgressDialog對這種情況來說很有用)。
2:特別是游戲,在子線程裡做移動的計算。
3:如果你的應用程序有一個耗時的初始化過程的話,考慮可以顯示一個Splash Screen或者快速顯示主畫面並異步來填充這些信息。在這兩種情況下,你都應該顯示正在進行的進度,以免用戶認為應用程序被凍結了。
簡介:即使你的應用程序是快速且響應靈敏 的,但一些設計仍然會給用戶造成問題——與其它應用程序或對話框未事先計劃的交互,意外的數據丟失,意料之外的阻塞等等。簡而言之,你應該竭盡全力去開發一個與系統和其它應用程序流暢交互的應用程序。
常見的流暢性問題:
1:一個應用程序的後台處理——例如,一個Service或者BroadcastReceiver—— 彈出一個對話框來響應一些事件。這可能看起來沒啥大礙,然而,當你的應用程序運行在真機上時,有可能你的應用程序在沒有獲得用戶焦點時後台處理顯示了一個對話框。因此,可能會出現在活躍的應用程序後方顯示了你的應用程序的對話框,或者從當前應用程序 奪取焦點顯示了一個對話框,而不管當前用戶正在做什麼(例如,正在打電話)。 種情況就應該使用Notification來處理,而不是奪取焦點和打斷用戶。
2:另一個例子是未能正確實現Activity的onPause()和其它生命周期方法而造成意外丟失了狀態或用戶數據。
流暢性設計指南
1:別丟棄數據
如果用戶在你的應用程序中正在編輯數據時,其它Activity出現了,這時,你的應用程序被殺死時可能丟失那些數據。
Android方式”是這樣做的:能接收和編輯用戶輸入的Android應用程序應該重寫onSaveInstanceState()方法,並以恰當的方式保存它們的狀態。 對於持久性的數據應該在onPause()方法裡面保存。
2:不要暴露原始數據
暴露原始數據,要求其它應用程序能夠理解你的數據的格式;如果你變更了格式,那麼,你將破壞那些沒有進行同步更新的應用程序。
“Android方式”是創建一個ContentProvider,以一種清晰的、深思熟慮的和可維護的API方式暴露你的數據給其它應用程序。使用ContentProvider,就好像是插入Java接口來分離和組裝兩片高耦合的代碼。這意味著你可以修改數據的內部格式,而不用修改由ContentProvider暴露的接口,這樣,也不會影響其它應用程序。
3:不要打斷用戶
如果用戶正在運行一個應用程序(例如,Phone程序),斷定對用戶操作的目的才是安全的。這也就是為什麼必須避免創建Activity,而是直接在當前的Activity中響應用戶的輸入。
那就是說,不要在BroadcastReceiver或在後台運行的Service中調用callActivity()。這麼做會中斷當前運行的應用程序,並導致用戶惱怒。也許更糟糕的是,你的Activity可能成為“按鍵強盜”,竊取了用戶要提供給前一個Activity的輸入。視乎你的應用程序所做的事情,這可能是個壞消息。
不選擇在後台直接創建Activity UI,取而代之的是,應該使用NotificationManager來設置Notification。它們會出現在狀態欄,並且用戶可以在他空閒的時候點擊它們,來查看你的應用程序向他顯示了什麼。
(注意,如果你的Activity已經在前台了,以上將不適用:這時,對於用戶的輸入,用戶期望的是看到下一個Activity來響應。)
4:有太多事情要做?在線程裡做
如果你的應用程序需要執行一些昂貴或耗時的計算的話,你應該盡可能地將它挪到線程裡。這將阻止向用戶顯示可怕的“Application Not Responding”對話框。
5:不要讓一個Activity超負荷
任何值得使用的應用程序都可能有幾個不同的屏幕,當設計你的應用程序的時候,把你的應用程序看作是Activity對象的集合。從長遠來看,這會使得你的代碼更加方便維護。
6:擴展系統主題
當設計你的UI時,你應該盡量避免太多自己的主題。相反的,使用同一個主題。你可以重寫或擴展你需要的主題部分,但至少在與其它應用程序相同的UI基礎上開始。
7:設計你的UI可以應付多屏幕分辨率
不同的Android設備可能支持不同的屏幕分辨率,應確保你的布局和圖片能足夠靈活地在不同的設備屏幕上正常顯示。
8:假設網絡很慢
你應該按照最小化的網絡訪問和帶寬來編寫你的代碼。
9:不要假定觸摸屏或鍵盤
創建應用程序的時候,不要假定特定的鍵盤布局——除非你真的想限定你的應用程序只運行在某些設備上。
10:節省設備電池
244.http請求的url含有中字符時,需要Uri編碼。Uri.encoder()245.使用androidstudio時,不知道什麼原因svn不見了Android S
Request處理流程RequestQueue類中有三個主要的隊列。調用RequestQueue.add(request)加入的請求會先加入mCacheQueue(優先級
概述ViewPager是Android開發中使用場景非常頻繁的控件,單一的動畫效果切換已經越來越不能滿足追求個性化的應用中。而ViewPager自身也帶有一個接口來處理頁
我們知道Android是以一個Activity為單位的,但是我們並沒有看到一個Activity是怎麼開始啟動的。今天我 們就從Android的源代碼開始講吧。Activi