題記
兩天前的幾乎所有時間,我一點也不看好Kotlin,但就在昨天我看到了一些Kotlin代碼片段時,改變看法了。如下:
private fun startCamera() {
// Create configuration object for the viewfinder use case
val previewConfig = PreviewConfig.Builder().apply {
setTargetResolution(Size(640, 480))
}.build()
// Build the viewfinder use case
val preview = Preview(previewConfig)
// Every time the viewfinder is updated, recompute layout
preview.setOnPreviewOutputUpdateListener {
// To update the SurfaceTexture, we have to remove it and re-add it
val parent = viewFinder.parent as ViewGroup
parent.removeView(viewFinder)
parent.addView(viewFinder, 0)
viewFinder.surfaceTexture = it.surfaceTexture
updateTransform()
}
// Bind use cases to lifecycle
// If Android Studio complains about "this" being not a LifecycleOwner
// try rebuilding the project or updating the appcompat dependency to
// version 1.1.0 or higher.
CameraX.bindToLifecycle(this, preview)
}
像上面那樣,
- apply中將屬性定義都括了起來
- 不用寫new
- set listener時直接拋過去個閉包
我滴個神啊,就是我理想的語言的。正巧CameraX的樣例也是Kotlin寫的,我也模仿着練手吧。
爲什麼出現問號氾濫問題
這麼一丟丟代碼,八個問號?????說好的解決了Java中空指針異常的問題,這麼解決的?????關鍵問題是,我一個viewFinder變量,用一次就要“?”一次,太不方便了,Java中我還可以在方法的開頭判斷下viewFinder==null
就return
的,這裏反而更復雜了。難以接受,寶寶不信。
問題的處理
有時候事情發生的就是這麼巧,寫CameraX代碼時,我記得看到了一行代碼,
private val displayManager by lazy {
requireContext().getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
}
馬上讓我想起了在Java中有時候定義個Lazy來實現延遲賦值,爲什麼會有這樣的需求呢,留個TODO吧:
- 完善Lazy實現博客
那Kotlin中這個lazy關鍵字很可能也是用來延遲賦值的。自己照着這行代碼寫一晌愣是沒把語法拼對,紅色的曲線一直在下邊飄着,如下:
心塞啊,只能去翻文檔了,文檔如下:
委託屬性
不想看文檔的,核心要點如下:
首先,Kotlin的關鍵字lazy確實可以實現延遲賦值,這一功能是依託於委託屬性這一語言特性的。lazy屬於委託的一個實現,Kotlin目前爲三種委託提供了實現,方便我們直接使用。lazy標準叫法叫延遲委託。
- 使用該委託時,值必須爲val,因爲Lazy中value定義爲val
- 改委託會求值時默認會加同步鎖,可以通過將LazyThreadSafetyMode值作爲參數傳遞個lazy函數來控制線程同步方式
基於以上,修改如下:
結果
perfect!!!幾乎已經沒有了問號。
問題延伸
之前看過一篇文章(其實很多地方都這樣講),說Kotlin通過“?”、“!!”處理了Java中的空指針問題。看完後認認真真的去了解了他們兩個在Kotlin中的應用,依然很難叫我信服。因爲我認爲空指針問題的避免絕不可能通過語言就處理掉了,而是應該人爲的在編碼上去避免該問題。具體的留個TODO:
- 空指針問題的處理