Свойство Kotlin CountDownTimer lateinit не было инициализировано, а CoreComponentFactory не найден - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь создать приложение таймера pomodoro.Раньше он работал, но после изменения некоторых вещей он ломался, а затем пытался воссоздать рабочий код.Я не могу понять, что не так.

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

Любая помощь приветствуется!

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

В итоге я понял, что это потому, что я говорю отменить, даже если он не работает.Чтобы решить эту проблему, я просто добавил оператор if, если он не работает:

    but_pomodoro.setOnClickListener{v ->
        if (timerState == TimerState.Running) {
            timer.cancel()
        }
        PrefUtil.setTimerLength(25)
        onTimerFinished()
    }

Спасибо за помощь, он указал мне правильное направление!

0 голосов
/ 12 декабря 2018

Почему вы должны определить таймер как поле lateinit, измените этот LOC на

private var timer: CountDownTimer? = null

Так что теперь вы можете четко обрабатывать таймер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...