2017-10-16 9 views
0

I créé minuterie (java.util.Timer) en Kotlin ainsi:se bloque avec minuterie KotlinNullPointerException intérieur fragment

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() 
      } 
     } 
    }) 
} 

Ce code se bloque sur la ligne 5 avec l'erreur:

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) 

Quand je créer minuterie à l'intérieur activity - cela fonctionne bien. Quel est le problème?

Répondre

0

Il me semble que textViewTimer ou activity est nulle sur cette ligne:

activity.runOnUiThread{...} 

Êtes-vous sûr que vous l'avez configuré correctement?

En particulier, vous ne pouvez pas compter sur Fragment.getActivity() (juste activity ici dans Kotlin) pour renvoyer une valeur non nulle à des points arbitraires après la création. Étant donné que vous l'exécutez dans une minuterie, il est possible que getActivity renvoie null. A côté: Les traces de la pile peuvent prêter à confusion lors de l'utilisation de lambda imbriqués comme celui-ci. Si vous regardez attentivement

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

Vous pouvez voir le $1 après scheduleAtFixedRate. Cette notation de dollar-signe est souvent employée pour se rapporter aux méthodes anonymes ou aux lambdas, et ici je crois qu'il se rapporte à votre gestionnaire de minuterie lui-même.

+0

vous avez raison. L'erreur était à l'intérieur de lambda. Le béguin semble vraiment confus :(merci – Rainmaker

0

En plus de la réponse de Myk Willis, vous combinez l'appel de sécurité (.?) ainsi que les opérateurs d'appel NPE (!!).

Cela signifie que si timerViewModel, timerViewModel.timerValue ou timerViewModel.timerValue.value est null alors qui peut aussi causer la NPE que vous voyez. Négocier efficacement l'avantage de l'utilisation de l'opérateur d'appel sécurisé.