Android 開發人員最常犯的 10 個錯誤:編程教程
已發表: 2022-03-11安卓。 這個平台有什麼不喜歡的? 它是免費的、可定制的、發展迅速的,不僅可以在您的手機或平板電腦上使用,還可以在您的智能手錶、電視和汽車上使用。
隨著最新的 Lollipop 更新,Android 編程繼續改進。 自最初的 AOSP 發布以來,該平台已經相當成熟,並將用戶期望設置得相當高。 看看新的 Material 設計模式看起來有多棒!
有成千上萬種不同的設備,具有不同的屏幕尺寸、芯片架構、硬件配置和軟件版本。 不幸的是,細分是為開放性付出的代價,即使作為高級 Android 程序員,您的應用程序在不同設備上的失敗方式也有數千種。
不管這麼大的分割,大部分的bug其實都是因為邏輯錯誤而引入的。 只要我們掌握了正確的基礎知識,這些錯誤就很容易避免!
這是一個 Android 編程教程,旨在解決 Android 開發人員最常犯的 10 個錯誤。
常見錯誤 #1:為 iOS 開發
令我高興的是,這種 Android 錯誤如今已不常見了(部分原因是客戶開始意識到 Apple 制定所有設計標準的日子早已一去不復返了)。 但是,我們仍然時不時地看到一個 iOS 克隆的應用程序。
不要誤會我的意思,我不是 Android 編程佈道者! 我尊重每一個推動移動世界向前發展的平台。 但是,現在是 2014 年,用戶使用 Android 已經有一段時間了,他們已經習慣了這個平台。 將 iOS 設計標準推給他們是一個糟糕的策略!
除非有非常好的理由違反準則,否則不要這樣做。 (谷歌一直這樣做,但從不復制粘貼。)
以下是此 Android 錯誤的一些最常見示例:
- 你不應該製作靜態標籤,它們不屬於底部(我指的是你的 Instagram)。
- 系統通知圖標不應有顏色。
- 應用程序圖標不應放置在圓角矩形內(除非那是您的實際徽標,例如 facebook)。
- 除了初始設置/介紹之外,啟動畫面是多餘的。 不要在其他場景中使用它們。
- 列表不應該有插入符號。
這些只是可能破壞用戶體驗的許多其他小事情中的一小部分。
常見錯誤 #2:為您的 Android 設備開發
除非您正在為單個平板電腦構建信息亭/促銷應用程序,否則您的 Android 應用程序可能不會在每台設備上看起來都很好。 以下是一些需要記住的 Android 編程技巧:
- 與密度無關的像素 (dp) 與普通像素 (px) 不同。
- 資源被多次包含以考慮不同的密度和方向。
- 9-patch drawables 被拉伸以適應屏幕。
確實有成千上萬種可能的場景,但一段時間後,您會產生一種用少數案例涵蓋所有場景的感覺。
你沒有成千上萬的設備? 不是問題。 Android Emulator 在復制物理設備方面非常出色。 更好的是,試試 Genymotion,它速度極快,並帶有許多不同的流行預設設備。
另外,您是否嘗試過旋轉設備? 所有的地獄都可以掙脫……
常見錯誤#3:不使用意圖
Intent 是 Android 的關鍵組件之一。 這是一種在應用程序的不同部分之間傳遞數據的方式,或者更好的是,在系統上的不同應用程序之間傳遞數據。
假設您有一個圖庫應用程序,可以通過 SMS 共享指向某些圖像的下載鏈接。 這兩個選項中哪一個看起來更合乎邏輯?
選項1:
請求 SEND_SMS 權限。
<uses-permission android:name="android.permission.SEND_SMS" />
- 編寫您自己的代碼以使用
SmsManager
發送短信。 - 向您的用戶解釋為什麼您的圖庫應用需要訪問可能需要花錢的服務,以及為什麼他們必須授予此權限才能使用您的應用。
選項 2:
啟動 SMS Intent 並讓專為 SMS 設計的應用程序完成工作
Intent sendIntent = new Intent(Intent.ACTION_VIEW); sendIntent.setData(Uri.parse("sms:" + telephoneNumber)); sendIntent.putExtra("sms_body", x); startActivity(sendIntent);
如果您有任何疑問,最好的解決方案是選項 2!
這種方法幾乎可以應用於任何事情。 分享內容、拍照、錄製視頻、挑選聯繫人、添加事件、打開與原生應用程序的鏈接等。
除非有充分的理由進行自定義實現(例如,應用過濾器的相機),否則請始終在這些場景中使用 Intent。 它將為您節省大量編程時間,並AndroidManifest.xml
不必要的權限。
常見錯誤 #4:不使用片段
前段時間在 Honeycomb 中,Android 引入了Fragments的概念。 將它們視為單獨的構建塊,它們具有自己的(相當複雜的)生命週期,存在於 Activity 中。 它們對優化各種屏幕有很大幫助,它們很容易由其父活動管理,可以隨意重用、組合和定位。
為每個應用程序屏幕啟動一個單獨的活動是非常低效的,因為系統會盡可能長時間地將它們保存在內存中。 殺死一個不會釋放其他人使用的資源。
除非您想深入了解 Android 核心並閱讀這篇反對使用 Fragment 的文章,否則您應該盡可能使用 Fragment。 它基本上說片段和游標加載器具有良好的預期目的,但實施不佳。
常見錯誤 #5:阻塞主線程
主線程只有一個目的:保持用戶界面響應。
儘管測量我們的眼睛/大腦可以感知的幀速率背後的科學是複雜的並且受很多因素的影響,但一般規則是任何低於 24 fps 且延遲大於 100 毫秒的東西都不會被認為是流暢的。
這意味著用戶的操作會有延遲的反饋,您編寫的 Android 應用程序將停止響應。 剝奪用戶對應用程序的控制會導致沮喪,沮喪的用戶往往會給出非常負面的反饋。
更糟糕的是,如果主線程被阻塞了一段時間(活動 5 秒,廣播接收器 10 秒),就會發生 ANR。

這在 Android 2.x 中很常見,以至於在較新的版本上,系統不允許您在主線程中進行網絡調用。
為避免阻塞主線程,請始終將工作線程/後台線程用於: 1. 網絡調用 2. 位圖加載 3. 圖像處理 4. 數據庫查詢 5. SD 讀/寫
常見錯誤 #6:重新發明輪子
“好吧,我不會使用主線程。 我將編寫自己的代碼,在後台線程中與我的服務器通信。”
不! 請不要那樣做! 網絡調用、圖像加載、數據庫訪問、JSON 解析和社交登錄是您在應用程序中最常做的事情。 不僅是您的,還有所有應用程序。 有一個更好的辦法。 還記得 Android 作為一個平台是如何成熟和成長的嗎? 以下是示例的快速列表:
- 使用 gradle 作為構建系統。
- 使用 Retrofit / Volley 進行網絡調用。
- 使用 Picasso 進行圖像加載。
- 使用 Gson / Jackson 進行 JSON 解析。
- 使用社交登錄的常見實現。
如果您需要實現某些東西,很可能它已經被編寫、測試和廣泛使用。 在編寫自己的代碼之前,先做一些基礎研究並閱讀一些 Android 編程教程!
常見錯誤 #7:不假設成功
偉大的。 我們了解到,有一種更好的方法來處理長時間運行的任務,為此我們正在使用有據可查的庫。 但用戶仍需等待。 這是不可避免的。 包裹不會立即發送、處理和接收。 有往返延遲,有網絡故障,有包裹丟失,有夢想破滅。
但這一切都是可以衡量的。 成功的網絡調用比不成功的更可能。 那麼為什麼在處理成功的請求之前等待服務器響應呢? 假設成功並處理失敗要好得多。 因此,當用戶點贊帖子時,點贊計數會立即增加,並且在不太可能發生呼叫失敗的情況下,會通知用戶。
在這個現代世界中,期望立即得到反饋。 人們不喜歡等待。 孩子們不想坐在教室裡獲取未來回報不確定的知識。 應用程序必須適應用戶的心理。
常見錯誤 #8:不理解位圖
用戶喜歡內容! 特別是當內容格式良好且看起來不錯時。 例如,圖像是非常好的內容,主要是因為它們每張圖像可以傳達一千個單詞。 它們還消耗大量內存。 很多內存!
在屏幕上顯示圖像之前,必須將其加載到內存中。 由於位圖是執行此操作的最常見方式,因此我們將為整個過程提供 Android 編程指南:
假設您想在屏幕上顯示您剛剛用相機拍攝的圖像。 為此所需的總內存使用以下公式計算: memory_needed_in_bytes = 4 * image_width * image_height;
為什麼是4? 好吧,最常見/推薦的位圖配置是ARGB_8888
。 這意味著對於我們繪製的每個像素,我們需要在內存中為 alpha、紅色、貪婪和藍色通道保留 8 位(1 個字節),以便正確顯示它。 還有其他選擇,例如RGB_565
配置,它需要的內存是ARGB_8888
的一半,但會失去透明度和顏色精度(同時可能會添加綠色色調)。
假設您有一台全新的設備,配備全高清屏幕和 12 MP 攝像頭。 您剛剛拍攝的圖片大小為 4000x3000 像素,顯示它所需的總內存為: 4 bytes * 4000 * 3000 = 48 MB
48 MB 的 RAM 僅用於單個圖像!? 好多啊!
現在讓我們考慮屏幕分辨率。 您試圖在具有 1920x1080 像素的屏幕上顯示 4000x3000 圖像,在最壞的情況下(全屏顯示圖像)您不應分配超過4 * 1920 * 1080 = 8.3 MB
的內存。
始終遵循有效顯示位圖的 Android 編程技巧:
- 測量顯示圖像的視圖。
- 相應地縮放/裁剪大圖像。
- 僅顯示可以顯示的內容。
常見錯誤 #9:使用深度視圖層次結構
佈局在 Android 中有一個 XML 表示。 為了繪製內容,需要解析 XML,需要測量屏幕,並且需要相應地放置所有元素。 這是一個需要優化的資源和耗時過程。
這就是 ListView(以及最近的 RecyclerView)的工作方式。
如果一個佈局已經膨脹一次,系統就會重用它。 但是,膨脹佈局必須在某個時候發生。
假設你想用圖像製作一個 3x3 的網格。 這樣做的一種方法是包含 3 個具有相同權重的LinearLayout
的垂直LinearLayout
,每個它們都包含 3 個具有相同權重的ImageViews
。
我們用這種方法得到了什麼? “嵌套權重對性能不利”的警告。
Android 編程界有一句我剛剛編造出來的說法: “只要不費吹灰之力,所有層次結構都可以扁平化” 。
在這種情況下, RelativeLayout
或GridLayout
將有效地替換嵌套的LinearLayouts
。
常見錯誤 #10:未將 minSdkVersion 設置為 14
好吧,這不是一個錯誤,但這是一種不好的做法。
Android 2.x 是開發這個平台的一個巨大里程碑,但有些東西應該被拋在後面。 支持舊設備會增加代碼維護的複雜性並限制開發過程。
數字很清楚,用戶已經繼續前進,開發人員不應該落後。
我知道這不適用於一些使用舊設備的大市場(例如印度),並且在 Facebook 應用程序上將minSdkVersion
設置為 14 意味著讓數百萬用戶沒有他們最喜歡的社交網絡。 但是,如果您剛開始並試圖為您的用戶創造美好的體驗,請考慮消除過去。 沒有資源的用戶,或者覺得需要升級他們的設備/操作系統的用戶,沒有動力去嘗試你的 Android 應用程序的高級版本並最終花錢購買它。
包起來
Android 是一個發展迅速的強大平台。 期望用戶跟上步伐可能是不合理的,但對於 Android 開發人員來說,這樣做至關重要。
了解 Android 不僅僅在我們的手機或平板電腦上更為重要。 它在我們的手腕上,在我們的客廳裡,在我們的廚房裡,在我們的汽車裡。 在我們開始擴展之前,掌握正確的基礎知識至關重要。