更強大的土司 – Toasty原始碼解析(上) Android Support Annotations
The usual Toast, but with steroids
Toast是我們在Android開發中幾乎都使用過的一個Class,你在書店隨手拿起一本初階教學書中都會講解到他,Android developer 官方給他的解釋為A toast is a view containing a quick little message for the user. The toast class helps you create and show those.
Toast.makeText(this, "Show Toast!", Toast.LENGTH_LONG).show();
只要這樣一行程式碼就可以成功顯示它
而我們這次的主角就是建立在原始Toast之上的一個library – Toasty,比起原始Toast類別,Toasty提供一個更加吸引人的色彩同時支持在文字前方顯示icon的效果,並採取GPL v3.0發布。
Toasty.success(this, "Success!", Toast.LENGTH_SHORT, true).show();
Toasty是一個十分小的library,比較引人注目的地方在於它利用了很多Android Support Annotations來優化程式。
Android Support Annotations是Andriod中一個用來輔助程式設計的註解,用法就像java中的小老鼠annotation一樣 ( 例如:@Override )
首先在程式一開頭就出現
@SuppressLint("InflateParams")
顧名思義,SuppressLint指的是壓制Lint,而Lint指的是Android開發中的一個檢查器,用來標記原始碼中,某些不安全、可疑的、不具結構性 ( 可能造成bug ) 的段落。而使用SuppressLint就是要抑制這個檢查錯誤訊息,SuppressLint的傳入值為字串 ( Android Lint Checks ) ,那至於有多少Android Lint Checks可以用呢?可以參考
Android Lint Checks - Android Studio Project Site
http://tools.android.com/tips/lint-checks
也可以搜尋到@SuppressLint("InflateParams")中的InflateParams所要抑制的錯誤訊息
SuppressLint通常用於抑制此API高於你的target SDK時Lint所產生的錯誤,一般來說會先判斷Android SDK版本,然後在低版本中採用舊方法,至於為了使新方法不跳出錯誤就要使用SuppressLint抑制了。
當然你也可以選擇在開發工具中關閉Lint,此時就不會再有任何錯誤訊息了(極度不建議)
我們很容易在網路上看到人比較@SuppressLint和@TargetApi,而差異其實就在於,@SuppressLint需要傳入的值是一個特定字串 ( Android Lint Checks ) ,也就是說我只抑制這個特定的問題;而@TargetApi需要傳入的值是一個int,也就是SDK的版本號,它抑制的是傳入之版本號以下、target SDK以上的所有API過高錯誤,等於是在直接拉高你的target SDK版本,所以當今天我們的問題是來自target SDK過低時,兩者確實十分相近,不過要格外注意的是,不管是@SuppressLint還是@TargetApi,他們都不會影響程式本體,也就是說你的APP發布時的target SDK不會更動,這時候如果APP沒有做好對低版本的支援,APP可能就會在運行時直接crash。
Toasty整體是一個static Class,這代表我們在使用時不用在額外new一個object出來,直接用Class名操作即可,在Toasty內部會呼叫一個名為ToastyUtils的final Class負責顏色渲染方面的功能,而我們主要分析的是Toasty.java這隻程式。
我們先看看它的屬性 ( property )
@ColorInt private static int WARNING_COLOR = Color.parseColor("#FFA900");
@ColorInt 表示這個int必須是直接代表顏色(AARRGGBB中轉過來的int),而不是代表某一顏色的id值,否則會報錯誤 ( the annotated element represents a packed color int )
再來看看method
@CheckResult public static Toast normal(@NonNull Context context, @NonNull CharSequence message) { return normal(context, message, Toast.LENGTH_SHORT, null, false); }
@NonNull表示這個傳入值不得為null。
@CheckResult表示這個method的回傳值一定要被使用,不論是拿去操作其他method(若是回傳的是object),或是被存入,總之就是要被使用。
例如:
Toasty.normal(yourContext, "Normal toast w/ icon", yourIconDrawable); //跳錯誤 Toasty.normal(yourContext, "Normal toast w/ icon", yourIconDrawable).show();//正常執行
Android Support Annotations的部分大概就到這裡了
下一回就可以直接來看整體的架構
參考資料
[1] Toasty github頁面
https://github.com/GrenderG/Toasty
[2] Android developer Toast頁面
https://developer.android.com/reference/android/widget/Toast.html
[3] Android developer ColorInt頁面
https://developer.android.com/reference/android/support/annotation/ColorInt.html
[4] Android developer CheckResult頁面
https://developer.android.com/reference/android/support/annotation/CheckResult.html
[5] Android developer NonNull頁面
https://developer.android.com/reference/android/support/annotation/NonNull.html
[6] lint – 維基百科
https://zh.wikipedia.org/wiki/Lint
[7] Android Lint Checks - Android Studio Project Site
http://tools.android.com/tips/lint-checks