該筆記主要記錄本人在讀《阿里巴巴Adroid開發手冊》的過程,自我感覺有疑惑或者值得記錄的地方。故並非對所有內容都有涉略。有興趣的朋友可以當作一個參考內容來看看。主要按該手冊的章節進行閱讀,記錄。後續有新的感悟還會補充。
二、Android資原始檔命名與使用
【自我感悟】1. Java按一定的規律來命名控制元件。做到多module時資源不會衝突以及模組命名定義清晰。
三、Android 基本元件
1【強制】Activity 間的資料通訊,對於資料量比較大的,避免使用 Intent + Parcelable 的方式,可以考慮 EventBus 等替代方案,以免造成 TransactionTooLargeException。
其他還可以搞個靜態內部類或者單例來儲存資料,在一個activity存,另一個取。這些方法本質上都是開闢一塊公共區域來存取資料。
(猜測前一個Activity的onStop中用EventBus傳送資料,另一個目標Activity的onCreate中對EventBus進行註冊)
2.【強制】避免在 BroadcastReceiver#onReceive()中執行耗時操作,如果有耗時工作, 應該建立 IntentService 完成,而不應該在 BroadcastReceiver 內建立子執行緒去做。
【原因】因為BroadcastReceiver生命週期很短,一旦結束,其所在程式就屬於空程式(沒有任何活動元件的程式),極易在系統記憶體不足時優先被殺死,而正在工作的子執行緒也會被殺死。所以,推薦開啟一個service,將耗時操作交給service,這樣可以提高宿主程式優先順序,保證耗時操作執行完成。
3.【推薦】當前 Activity 的 onPause 方法執行結束後才會執行下一個 Activity 的 onCreate 方法,所以在 onPause 方法中不適合做耗時較長的工作,這會影響到頁面之間的跳 轉效率。
4.對於只用於應用內的廣播,優先使用 LocalBroadcastManager 來進行註冊 和傳送,LocalBroadcastManager 安全性更好,同時擁有更高的執行效率。
【原因】LocalBroadcastManager只在app內進行廣播,不會在各app之間進行傳播。可防止自己的廣播資訊被別有用心的人監聽。(跨Activity資料傳遞本質上是找了一個公共區域用來存放資料)
四、UI 與佈局
1. 【強制】佈局中不得不使用 ViewGroup 多重巢狀時,不要使用 LinearLayout 巢狀,改用 RelativeLayout,可以有效降低巢狀數。
【原因】同一個佈局在很多情況下RelativeLayout下的佈局所需的層次會小於LinearLayout所需的佈局可減少過度繪製。但是在佈局相同的情況下用LinearLayout更加好。因為RelativeLayout會進行上下和左右兩次measure
2.【推薦】在 Activity 中顯示對話方塊或彈出浮層時,儘量使用 DialogFragment,而非 Dialog/AlertDialog,這樣便於隨 Activity 生命週期管理對話方塊/彈出浮層的生命週期。
3.【推薦】文字大小使用單位 dp,view 大小使用單位 dp。對於 Textview,如果在文 字大小確定的情況下推薦使用 wrap_content 佈局避免出現文字顯示不全的適配問 題。
【原因】sp會隨著使用者在設定中設定系統大小不同而變化。字型變化後有可能導致app適配的問題。同時國內的rom碎片化也有可能導致各種顯示問題。而dp會一直保持現有大小。但是這個的弊端是使用者調整系統的字型大小後,你自身app的大小不能進行變化。有點違背系統的感覺。個人感覺用哪個根據自己需要吧。目前我還是用的sp
4.【推薦】不能在 Activity 沒有完全顯示時顯示 PopupWindow 和 Dialog。
【原因】PopupWindow不像對話方塊那樣從螢幕的固定位置彈出,而是依賴於錨點控制元件物件的位置,所謂錨點控制元件物件,就是介面元件中的某個控制元件,PopupWindow的展示和功能都是以它為核心,作為錨點控制元件的擴充套件互動介面,以增強該控制元件物件的功能。彈出視窗與描點控制元件有著緊密的聯絡,在構造並展示彈出視窗前,需要保證錨點控制元件所在的控制元件樹已經與視窗管理服務建立連線,因為在彈出視窗的展示過程中,需要通過該視窗物件來獲取相關資訊。在介面元件的構造過程中,視窗連線的建立是個非同步過程,也就是說,當Activity.onCreate()等函式被呼叫時,介面與視窗管理服務的雙向通訊連線尚未建立,如果在此時構造彈出視窗則會丟擲異常。因此,如果期望在介面元件展現之處便構造彈出視窗,可以將彈出視窗物件構造也轉換成一個非同步過程。即view.post(new running()).
5.【強制】不能使用 ScrollView 包裹 ListView/GridView/ExpandableListVIew;因為這 樣會把 ListView 的所有 Item 都載入到記憶體中,要消耗巨大的記憶體和 cpu 去繪製圖 面。
說明:ScrollView 中巢狀 List 或 RecyclerView 的做法官方明確禁止。除了開發過程中遇到的各種視覺和互動問題,這種做法對效能也有較大損耗。ListView 等 UI 元件自身有垂直滾動功能,也沒有必要在巢狀一層 ScrollView。目前為了較好的 UI 體驗,更貼近 Material Design 的設計,推薦使用 NestedScrollView
PS:本人測試NestedScrollView中新增ListView也會全部新增。類似於要使用這種需求。可以用阿里的Vlayout佈局。或者ListView新增HeadView等。
五、程式、執行緒與訊息通訊
1.【強制】不要通過 Intent 在 Android 基礎元件之間傳遞大資料(binder transaction 快取為 1MB),可能導致 OOM。
2.【強制】新建執行緒時,必須通過執行緒池提供(AsyncTask 或者 ThreadPoolExecutor 或者其他形式自定義的執行緒池),不允許在應用中自行顯式建立執行緒。
【原因】本人在開發app中發現如果多人一起開發並且都個人建立執行緒則會導致app內執行緒亂飛。嚴重的如華為的某些機制線上程數達到500時會導致crash。建議根據業務定義幾個全域性統一的執行緒庫。
3.【強制】執行緒池不允許使用 Executors 去建立,而是通過 ThreadPoolExecutor 的方 式,這樣的處理方式讓寫的同學更加明確執行緒池的執行規則,規避資源耗盡的風險。
4.【強制】不要在非 UI 執行緒中初始化 ViewStub,否則會返回 null。
六、檔案與資料庫
1. 【強制】任何時候不要硬編碼檔案路徑,請使用 Android 檔案系統 API 訪問。
android.os.Environment#getExternalStorageDirectory() android.os.Environment#getExternalStoragePublicDirectory() android.content.Context#getFilesDir() android.content.Context#getCacheDir
2.【推薦】SharedPreference 提交資料時,儘量使用 Editor#apply(),而非 Editor#commit()。一般來講,僅當需要確定提交結果,並據此有後續操作時,才使 用 Editor#commit()。
說明:SharedPreference 相關修改使用 apply 方法進行提交會先寫入記憶體,然後非同步寫入 磁碟,commit 方法是直接寫入磁碟。如果頻繁操作的話 apply 的效能會優於 commit,apply 會將最後修改內容寫入磁碟。但是如果希望立刻獲取儲存操作的結果,並據此做相應的其他操作,應當使用 commit.
七、Bitmap、Drawable 與動畫
這節講到的內容基本上都有所瞭解。所以不做記錄了。主要就是要注意不要OOM。
八、安全
1.不要把敏感資訊列印到 log 中.
【方法】在產品的線上版本中關閉除錯介面,不要輸出敏感資訊。方法參考 https://mp.weixin.qq.com/s/DE4gr8cTRQp2jQq3c6wGHQ 黑科技:用Proguard的-assumenosideeffects清除log
這節的內容瞭解的基本都瞭解。有些內容真的基本沒怎麼涉略過。後續要好好研究一下。