首页 > 解决方案 > Kotlin CountDownTimer lateinit 属性尚未初始化且未找到 CoreComponentFactory

问题描述

我正在尝试创建一个番茄计时器应用程序。它以前可以工作,但是在更改了一些内容之后,它会中断,然后尝试重新创建工作代码。我不知道出了什么问题。

Logcat我得到两者

没有找到“android.support.v4.app.CoreComponentFactory

在失败和关闭后的一段时间,和

'kotlin.UninitializedPropertyAccessException:lateinit 属性计时器尚未初始化'

失败后直接。我已经尝试gradle按照其他后期初始化代码问题中的建议更改文件,但这似乎并非如此。

package com.bignerdranch.android.carrottimer

import android.os.Bundle
import android.os.CountDownTimer
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.text.Editable
import android.text.TextWatcher
import android.view.Menu
import android.view.MenuItem
import android.widget.EditText
import android.widget.Switch
import android.widget.TextView
import android.widget.Toast
import com.bignerdranch.android.carrottimer.util.PrefUtil

import kotlinx.android.synthetic.main.activity_timer.*
import kotlinx.android.synthetic.main.content_timer.*
import java.util.*

class TimerActivity : AppCompatActivity() {

enum class TimerState{
    Stopped, Paused, Running
}

private lateinit var timer: CountDownTimer
private var timerLengthSeconds: Long = 0
private var timerState = TimerState.Stopped

var secondsRemaining: Long = 0

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_timer)
    supportActionBar?.setIcon(R.drawable.ic_timer)
    supportActionBar?.title = "    Carrot Timer"

    val sw = findViewById<Switch>(R.id.switch1)
    sw?.setOnCheckedChangeListener { _, isChecked ->
        val msg = if (isChecked) "ON" else "OFF"
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
        sw.text = msg
    }

    but_pomodoro.setOnClickListener{v ->
        timer.cancel()
        PrefUtil.setTimerLength(25)
        onTimerFinished()
    }

    but_short.setOnClickListener{v ->
        timer.cancel()
        PrefUtil.setTimerLength(5)
        onTimerFinished()
    }

    but_long.setOnClickListener{v ->
        timer.cancel()
        PrefUtil.setTimerLength(10)
        onTimerFinished()
    }

    fab_start.setOnClickListener{v ->
        startTimer()
        timerState =  TimerState.Running
        updateButtons()
    }

    fab_pause.setOnClickListener { v ->
        timer.cancel()
        timerState = TimerState.Paused
        updateButtons()
    }

    fab_stop.setOnClickListener { v ->
        timer.cancel()
        onTimerFinished()
    }
}

override fun onResume() {
    super.onResume()

    initTimer()
}

override fun onPause() {
    super.onPause()

    if (timerState == TimerState.Running){
        timer.cancel()
    }

    PrefUtil.setPreviousTimerLengthSeconds(timerLengthSeconds, this)
    PrefUtil.setSecondsRemaining(secondsRemaining, this)
    PrefUtil.setTimerState(timerState, this)
}

private fun initTimer(){
    timerState = PrefUtil.getTimerState(this)

    if (timerState == TimerState.Stopped)
        setNewTimerLength()
    else
        setPreviousTimerLength()

    secondsRemaining = if (timerState == TimerState.Running || timerState == TimerState.Paused)
        PrefUtil.getSecondsRemaining(this)
    else
        timerLengthSeconds

    if (timerState == TimerState.Running)
        startTimer()

    updateButtons()
    updateCountdownUI()
}

private fun onTimerFinished(){
    timerState = TimerState.Stopped

    setNewTimerLength()

    PrefUtil.setSecondsRemaining(timerLengthSeconds, this)
    secondsRemaining = timerLengthSeconds

    updateButtons()
    updateCountdownUI()
}

private fun startTimer(){
    timerState = TimerState.Running

    timer = object : CountDownTimer(secondsRemaining * 1000, 1000) {
        override fun onFinish() = onTimerFinished()

        override fun onTick(millisUntilFinished: Long) {
            secondsRemaining = millisUntilFinished / 1000
            updateCountdownUI()
        }
    }.start()
}

private fun setNewTimerLength(){
    val lengthInMinutes = PrefUtil.getTimerLength(this)
    timerLengthSeconds = (lengthInMinutes * 60L)
}

private fun setPreviousTimerLength(){
    timerLengthSeconds = PrefUtil.getPreviousTimerLengthSeconds(this)
}

private fun updateCountdownUI(){
    val minutesUntilFinished = secondsRemaining / 60
    val secondsInMinuteUntilFinished = secondsRemaining - minutesUntilFinished * 60
    val secondsStr = secondsInMinuteUntilFinished.toString()
    textView_countdown.text = "$minutesUntilFinished:${if (secondsStr.length == 2) secondsStr else "0" + secondsStr}"
}

private fun updateButtons(){
    when (timerState) {
        TimerState.Running ->{
            fab_start.isEnabled = false
            fab_pause.isEnabled = true
            fab_stop.isEnabled = true
        }
        TimerState.Stopped -> {
            fab_start.isEnabled = true
            fab_pause.isEnabled = false
            fab_stop.isEnabled = false
        }
        TimerState.Paused -> {
            fab_start.isEnabled = true
            fab_pause.isEnabled = false
            fab_stop.isEnabled = true
        }
    }
}


override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_timer, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return super.onOptionsItemSelected(item)
}
}

任何帮助表示赞赏!

标签: androidkotlin

解决方案


为什么必须将计时器定义为lateinit字段,将此 LOC 更改为

private var timer: CountDownTimer? = null

所以现在你可以清楚地处理定时器了。


推荐阅读