之前在 Save ArrayList to SharedPreferences 提到過,如何將 ArrayList 物件存到 SharedPreferences 裡,最近看到一個更棒的方式,那就是使用 Gson。
假設我現在有個 MyObject 物件想要存起來,可以這樣寫:
要取出來時:
回到之前 ArrayList 的問題,儲存可以改用上面範例來處理,至於取出的方法需要改寫成這樣:
比起原本的程式碼,變得乾淨俐落許多!
Reference:
http://stackoverflow.com/questions/5418160
Holidaybear's
2015/08/18
2015/04/28
Test Your Deep Links
今天看文件才想到 adb 有提供指令可以直接發 Intent 給 App,而且還能帶 URI data,這樣要用來測試 protocol 就方便多了!
Reference:
https://developer.android.com/training/app-indexing/deep-linking.html#testing-filters
Reference:
https://developer.android.com/training/app-indexing/deep-linking.html#testing-filters
2015/04/27
android.database.CursorWindowAllocationException
當 Cursor 沒有確實關閉並且累積到一定數目時,App 就會出現異常報錯,無法查詢資料庫,甚至 crash。這邊記錄一些容易出錯的例子:
。提前返回
有時會沒注意到在調用 close() 之前就 return 了,尤其在比較複雜的程式碼中就可能會疏忽。
。異常處理
在還沒執行 close() 之前就因為處理 exception 而跳過。
要避免這種情形,應該要把 close() 放到 finally 裡確保它會執行。
另外我們也可以在 Cursor 的建構及關閉時加上 log 來測試及偵錯。
這樣就能清楚檢查是否有 Cursor 未確實關閉,但要先等 App 完全結束程序時再做,因為有些 Cursor 可能仍在背景運行中。
Reference:
http://oteku.blogspot.tw/2013/11/how-to-detect-android-cursor-leak-en.html
。提前返回
有時會沒注意到在調用 close() 之前就 return 了,尤其在比較複雜的程式碼中就可能會疏忽。
。異常處理
在還沒執行 close() 之前就因為處理 exception 而跳過。
要避免這種情形,應該要把 close() 放到 finally 裡確保它會執行。
另外我們也可以在 Cursor 的建構及關閉時加上 log 來測試及偵錯。
這樣就能清楚檢查是否有 Cursor 未確實關閉,但要先等 App 完全結束程序時再做,因為有些 Cursor 可能仍在背景運行中。
Reference:
http://oteku.blogspot.tw/2013/11/how-to-detect-android-cursor-leak-en.html
2015/04/26
java.util.ConcurrentModificationException
前陣子在做 for-each 執行某項過濾功能時遇到這個異常報錯,原因在於 for-each 的架構是不能使用於過濾需求的,一旦變動了集合的內容便會發生錯誤。在這邊可以使用 Iterator 調動集合的方式來解決,在多個執行緒中也能做到同步。
另外如果集合不大,也可以使用 counted loop 來處理。
Reference:
http://stackoverflow.com/a/223929/1770125
另外如果集合不大,也可以使用 counted loop 來處理。
Reference:
http://stackoverflow.com/a/223929/1770125
2015/03/01
POJO
POJO,全名為 Plain Old Java Object。它是一個簡單的 Java Object 概念定義,可以包含邏輯處理,以下三種情況不能稱作 POJO:
1. 繼承 Java frameworks 的 class
2. 實作 Java frameworks 的 interface
3. 包含 Java frameworks 的 annotation
Reference:
http://martinfowler.com/bliki/POJO.html
http://en.wikipedia.org/wiki/Plain_Old_Java_Object
1. 繼承 Java frameworks 的 class
2. 實作 Java frameworks 的 interface
3. 包含 Java frameworks 的 annotation
Reference:
http://martinfowler.com/bliki/POJO.html
http://en.wikipedia.org/wiki/Plain_Old_Java_Object
Programmatically Declare Styleable In Custom View
在我們設計 custom View 的時候,一般都會想要定義一些專屬的 attributes 放在 attrs.xml 裡面,方便之後可以調整它的參數來因應 layout 規格。例如在 Chris Banes 的 FloatLabelLayout 中,他先在 attrs.xml 定義了每個方向的 padding,以及要用作 label 的 hint 和 TextAppearance,
然後在 FloatLabelLayout.java 取得外部利用這些 attributes 所設定的數值,進而調整裡面需要變動的元件。
但是有些時候,我們可能想要直接在程式碼中定義這些行為,那該如何實作呢?
在這個例子中,我們先宣告了 styleable 這個 int array,放入需要用到的 attributes,接著調用 Context#obtainStyledAttributes() 傳回一個 TypedArray 的物件,裡面便會包含 reference 到這些 attributes 所設定的數值,再來就可以選擇適當的 method 來取用了。
這邊有幾個需要注意的地方,由於 context.obtainStyledAttributes() 內部設計預設是認定 styleable 中的 attributes 是排序過的,所以他回傳回來的數值是依其在 native 的順序寫入到 TypedArray,若是我們的 styleable 沒 sort 過,就會得到非預期的結果;另外就是從 TypedArray 取值時傳入的是 attribute 在 styleable 的 index,而非 attribute 本身。
Reference:
http://droidux.com/programmatically-declare-styleable-custom-view/
然後在 FloatLabelLayout.java 取得外部利用這些 attributes 所設定的數值,進而調整裡面需要變動的元件。
但是有些時候,我們可能想要直接在程式碼中定義這些行為,那該如何實作呢?
在這個例子中,我們先宣告了 styleable 這個 int array,放入需要用到的 attributes,接著調用 Context#obtainStyledAttributes() 傳回一個 TypedArray 的物件,裡面便會包含 reference 到這些 attributes 所設定的數值,再來就可以選擇適當的 method 來取用了。
這邊有幾個需要注意的地方,由於 context.obtainStyledAttributes() 內部設計預設是認定 styleable 中的 attributes 是排序過的,所以他回傳回來的數值是依其在 native 的順序寫入到 TypedArray,若是我們的 styleable 沒 sort 過,就會得到非預期的結果;另外就是從 TypedArray 取值時傳入的是 attribute 在 styleable 的 index,而非 attribute 本身。
Reference:
http://droidux.com/programmatically-declare-styleable-custom-view/
2015/02/16
Avoid float and double if exact answers are required
float 和 double 主要是被設計用作科學及工程運算,若是需要精確結果的商業計算,它們並不適合,原因在於它們不能準確地表達 0.1 或任何 10⁻¹ 的倍數。
假設你口袋有 $1.03,而你花了 42¢,那會剩下多少?
不幸地,它的輸出結果是 0.6100000000000001,這不是唯一的特殊案例;假設你口袋有 $1,你買了 9 個 10¢ 的物品,那會找回多少零錢?
根據這個結果,你會拿回 $0.09999999999999998。
我們可能會覺得只要利用輸出前幾位數做四捨五入來 work around 就可以了,但這招並不是每次都能奏效。再來舉一個例子,假設現在你口袋有 $1,架上擺著糖果,價格依序為 10¢、20¢、30¢,依此類推,如果從第一顆糖果開始買起,你可以買多少顆糖果,並且能找回多少零錢?
當你跑完這段程式碼,你會發現你可以買 3 顆糖果,然後找回 $0.3999999999999999,這結果當然是錯的。要解決這個情況,我們必須改用 BigDecimal 來處理商業計算。
這次我們得到了正確的答案,你可以買 4 顆糖果,找回 $0.00。
不過,使用 BigDecimal 也有缺點,它寫起來不是很方便,而且格式也麻煩,不容易 review。另外一個方法就是視情況使用 int 或 long 來代換,像是在這個例子中,因為數值不大,我們可以把單位都改用分來計算。
Reference:
http://stackoverflow.com/questions/5257166
《Effective Java》Item 48
假設你口袋有 $1.03,而你花了 42¢,那會剩下多少?
不幸地,它的輸出結果是 0.6100000000000001,這不是唯一的特殊案例;假設你口袋有 $1,你買了 9 個 10¢ 的物品,那會找回多少零錢?
根據這個結果,你會拿回 $0.09999999999999998。
我們可能會覺得只要利用輸出前幾位數做四捨五入來 work around 就可以了,但這招並不是每次都能奏效。再來舉一個例子,假設現在你口袋有 $1,架上擺著糖果,價格依序為 10¢、20¢、30¢,依此類推,如果從第一顆糖果開始買起,你可以買多少顆糖果,並且能找回多少零錢?
當你跑完這段程式碼,你會發現你可以買 3 顆糖果,然後找回 $0.3999999999999999,這結果當然是錯的。要解決這個情況,我們必須改用 BigDecimal 來處理商業計算。
這次我們得到了正確的答案,你可以買 4 顆糖果,找回 $0.00。
不過,使用 BigDecimal 也有缺點,它寫起來不是很方便,而且格式也麻煩,不容易 review。另外一個方法就是視情況使用 int 或 long 來代換,像是在這個例子中,因為數值不大,我們可以把單位都改用分來計算。
Reference:
http://stackoverflow.com/questions/5257166
《Effective Java》Item 48
訂閱:
文章 (Atom)