2017-10-16 41 views
0

我在科特林創建定時器(java.util.Timer中)是這樣的:與KotlinNullPointerException計時器崩潰內部片段

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 
    super.onViewCreated(view, savedInstanceState) 
    buttonStart.setOnClickListener({ 
     val timer = Timer("schedule", true) 
     timer.scheduleAtFixedRate(1000, 1000) { 
      if (timerViewModel?.timerValue?.value!! > 0){ 
       timerViewModel?.timerValue?.value = timerViewModel?.timerValue?.value!! - 1 
       activity.runOnUiThread { textViewTimer.text = timerViewModel?.timerValue?.value?.toString() } 
      } else { 
       cancel() 
      } 
     } 
    }) 
} 

在與錯誤第五行此代碼崩潰:

kotlin.KotlinNullPointerException 
      at com.dmitry.timer.views.TimerFragment$onViewCreated$1$$special$$inlined$scheduleAtFixedRate$1.run(Timer.kt:145) 
      at java.util.Timer$TimerImpl.run(Timer.java:284) 

當我在activity內部創建計時器 - 它工作正常。 問題是什麼?

回答

0

它看起來對我來說,textViewTimeractivity爲null,在這條線:

activity.runOnUiThread{...} 

你確定你已經正確設置它?

特別是,您不能依賴Fragment.getActivity()(僅在Kotlin的activity)在創建後的任意點處返回非空值。由於您正在計時器中執行此操作,因此getActivity可能返回空值。

另外:使用這樣的嵌套lambdas時,堆棧跟蹤可能會引起混淆。如果您在

at com.dmitry.timer.views.TimerFragment$onViewCreated$1$$special$$inlined$scheduleAtFixedRate$1.run(Timer.kt:145) 

仔細看可以看到scheduleAtFixedRate$1。那個美元符號表示法經常用來指代匿名方法或lambda表達式,在這裏我相信它指的是你的定時器處理程序本身。

+0

你是對的。這個錯誤在lambda裏面。美眉真的看起來很混亂:(謝謝 – Rainmaker

0

除了Myk Willis的回答外,您還將安全呼叫(.?)以及NPE呼叫(!!)運營商相結合。

這意味着如果timerViewModeltimerViewModel.timerValuetimerViewModel.timerValue.valuenull那麼這也可以導致您看到的NPE。有效地否定使用安全呼叫操作員的好處。