Annotate interface function that must call super - android

I'm creating interface and some function in it has a body.
It's required, that class that implements this interface must call super in overriding function before executing other code.
How can I do this?
interface Watcher {
fun funWithoutBody()
fun startWatching() {
//do some important stuff which must be called
}
}

I've accidentally found, what I was looking for. It's a #CallSuper annotation available in androidx.annotation package. Docs
Use the #CallSuper annotation to validate that an overriding method
calls the super implementation of the method. The following example
annotates the onCreate() method to ensure that any overriding method
implementations call super.onCreate():
#CallSuper
protected fun onCreate(savedInstanceState: Bundle?) {
}

Android Studio / IntelliJ IDEA does this sort of thing in some cases but it isn't done through annotations but through code inspection.
e.g. MissingSuperCall is an Android Lint Check for which IntelliJ IDEA supports (Integration with Android Lint tool in IntelliJ IDEA 11.1 | IntelliJ IDEA Blog).
You can create your own custom inspection if you are using Android Studio or IntelliJ IDEA: IntelliJ IDEA 2016.2 Help :: Creating Custom Inspections.

You could just make startWatching abstract and call it in another function. E.g.:
interface Watcher {
fun funWithoutBody()
fun userDefinedStartWatching()
fun startWatching() {
//insert code you'd normally want to be called when using super()
userDefinedStartWatching()
}
}

Related

Play Billing 5.0.0 Kotlin - How to override onProductDetailsResponse()?

please reference this doc.
It states: "To handle the result of the asynchronous operation, you must also specify a listener which implements the ProductDetailsResponseListener interface. You can then override onProductDetailsResponse(), which notifies the listener when the query finishes, as shown in the following example:"
Trouble is, there's no such listener in the Kotlin example (there is one in the Java example.)
When I add:
override fun onProductDetailsResponse() { ... }
I get "nothing to override" from the SDK. Is it the case that Java needs the interface but Kotlin doesn't?
Thank you!

How to use multiple scopes in a #RestrictTo annotation

I'm using #RestrictTo annotation to denote that a function should be used in only in subclasses or tests.
To do that I use the following syntax:
#RestrictTo(value = [SUBCLASSES, TESTS])
public override fun onCleared() {
// Expose protected fun onCleared for tests
}
At first it seemed to be working but my teammates reported Android Studio showing this warning:
I could reproduce this after building the project again.
This error goes away if I remove the TESTS scope from the annotation as if the annotation does not support multiple scopes in values.
Do you think if this is the intended behavior of the annotation?
Can you think another way to restrict a function to the union of two different scopes?
Thanks in advance

Android Annotation Processor: Invoke annotated method with a condition

I'm quite new to building a custom annotation processor,
I've followed some tutorials & guides over here on SO too but been stuck on adding a condition for the annotated method.
The problem:
I have a custom annotation directed only for methods,
say, #RUN(isDebug: Boolean) & the method would be:
#RUN(isDebug = true)
private fun runInDebugOnly() {
....
}
#RUN(isDebug = false)
private fun runInReleaseOnly() {
....
}
So in my Annotation Processor,
is it possible to execute these functions with a condition?
I know the concept of generating a custom class & methods inside it,
But how to exactly intercept the method & use the generated method instead.
Any guidance would be appreciated.
An annotation processor only runs at compile time, and is usually used to generate new classes or code.
Sounds to me like you want to generate a new method at compile time which will call the correct annotated method depending on the build type.
e.g. when you run a debug build you want to have
fun myNewMethod() {
runInDebugOnly()
}
but when you run a release build you want to have
fun myNewMethod() {
runInReleaseOnly()
}
The rest of your app will just call myNewMethod() and it won't care about the implementation.
You could achieve this another way without using an annotation processor
fun myNewMethod() {
if (Build.DEBUG) {
runInDebugOnly()
} else if (Build.RELEASE) {
runInReleaseOnly
}
}
Is this the kind of thing you're after?

Return internal class calling object function

I'm testing with Kotlin and I'm writing a small library to be imported and used by a test App project.
In the library project I marked my classes as internal because I don't want them to be visible for the App project, but I would like to have a single entry point for the library, and for that I am using a Kotlin object like shown below
LIBRARY
object Library {
fun getComponent() = AwesomeComponent()
}
internal class AwesomeComponent() {
// some implementation
}
TEST APP
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val component = Library.getComponent()
}
}
The problem is that this doesn't compile because the function in the Library object returns an internal type and therefore need to be marked as internal as well, but doing so would hide the function from the TestApp.
Another option would be to not have the internal modifier at all so the TestApp can see the Library method, but then it can also see the classes inside the Library project
Is there an easy solution that I am overlooking here or does it need to go through re-planning of packages and structure of the Library project? (not sure how to do it in that case)
You have to publish some sort of public API for the app module to be able to use the component that the getComponent() method returns. If you want to publish minimal information about your library, you can have it return an interface that contains only the publicly available method calls to the library, and make your class implement that interface:
object Library {
fun getComponent(): IAwesomeComponent = AwesomeComponent()
}
interface IAwesomeComponent {
// methods you want to call on the component in the app module
}
internal class AwesomeComponent(): IAwesomeComponent {
// implementations of the interface methods
}

android #Override error before function

I am having this error:
#Override
public void paint(Canvas canvas) {
}
The method paint(Canvas) of type MainActivity must override or implement a supertype method.
The error disappears only if I remove the #Override before the method.
I have already set in project properties java compiler on level 1.6
Can you help me?
If you are extending an Activity you can't override the paint method.
Paint is not an Activity method. You can only override existent methods from the class you are extending.
Also I never used Paint. Did you want to override the onDraw(Canvas) from the View?
It seems you are trying to override a method that doesn't "exist" in MainActivity's superclass.
Some possible reasons (and solutions):
You forgot to add extends ... to the class you think it (MainActivity) inherits from.
You confused the method name, and it shouldn't be paint() - if this is the case - just change the method name
It is a new method for this class - and the annotation #Override should be deleted.
You changed the arguments for the original method - and you are overloading instead of overriding. You should stick with the same arguments if you really want to override it, or remove the #Override annotation if you are after overloading.
if indeed the method that you want to override exists in the parent class then make sure you are compiling with at least java 1.6
So left click on your project -> properties -> Java Compiler -> Select at least java 1.6 then clean the project and rebuild.

Categories

Resources