Home > Net >  Can an abstract class be expanded within an object expression in kotlin?
Can an abstract class be expanded within an object expression in kotlin?

Time:03-31

So I'm writing a piece of code to add a pause and resume functionality into the abstract class CountDownTimer (Android.os.CountDownTimer). I'm using the functionality only within this one activity and therefore am just using an object expression to create an anonymous class called sequencetimer. The code looks something like this:

public var sequencetimer = object : CountDownTimer(30000, 1000) {
    public var timeremaining : Long = 0

    override fun onTick(millisUntilFinished: Long) {
        findViewById<TextView>(R.id.textView8).apply {
            text = ("seconds remaining: "   millisUntilFinished / 1000)
        }
    }

    override fun onFinish() {
        findViewById<TextView>(R.id.textView8).apply {
            text = "done"
        }
    }

    public fun pauseTimer() {
        timeremaining = findViewById<TextView>(R.id.textView8).text as Long
        cancel()
    }

    public fun resumeTimer() {
        onTick(timeremaining)
        start()
    }
}

Now I want to call the pauseTimer and resumeTimer functions that I added whenever my activity pauses or resumes like so:

override fun onPause() {
    super.onPause()
    sequencetimer.pauseTimer()
}

override fun onResume() {
    super.onResume()
    sequencetimer.resumeTimer()
}

The code however keeps throwing me an unresolved reference error for the functions pauseTimer() and resumeTimer(), even though the sequencetimer object is declared within the activity class and I can execute all the other functions such as sequencetimer.onTick() and sequencetimer.start() (however I can also not acces the public var timeremaining). Does anyone have any idea what the issue here is? Or is it simply not possible to expand/extend an abstract class within an anonymous object expression (I would have expected android studio to then throw some type of error)?

CodePudding user response:

There are some issues with your code.

First issue I see is that public var sequencetimer. With kotlin keywords public, protected, internal you declare to compiler that sequencetimer would be accessible outside of your android activity class's scope. But object created as anonymous class in your activity class. Kotlin compiler decides that the only solution is marking sequencetimer as CountDownTimer.

// byte code
public final getSequencetimer()Landroid/os/CountDownTimer;
  @Lorg/jetbrains/annotations/NotNull;() 

Secondly, resumeTimer() will call onTick(12345L) once and restart the timer from the millisInFuture 30_000L.

It would be better you create a new count down timer for the remaining time. And please, decrease the count down interval or you will see the seconds inconsistent 30, 28, 27, 26, 26, 24, ...

Hope, it helps.

CodePudding user response:

As you said yourself: you create anonymous class. That means this class doesn't exists from the developer point of view and the type of sequencetimer is just CountDownTimer which doesn't have pauseTimer() and resumeTimer() functions. You need to create a regular, named class, so it can be referenced in the code.

Alternatively, you can make sequencetimer a private var. In this case Kotlin assumes this is internal stuff and provides some kind of a shortcut. It conditionally permits this kind of operation, even if normally it should not be possible. This behavior is described in the docs: https://kotlinlang.org/docs/object-declarations.html#using-anonymous-objects-as-return-and-value-types

  • Related