Open AndroidDeveloperLB opened 2 years ago
Hmm, this sounds questionable to me.
@UiThread fun
means “call this method from UI thread only”,
@UiThread abstract fun
means “this method is guaranteed to be called from UI thread”.
But overridden method could be unconstrained, this is up to implementer. And the implementer themself may call it from any thread knowing that the method is pure or concurrent.
The example is ProgressBar
class which extends @UiThread View
but has some synchronized
methods.
But if I call the function (either inside the abstract class or from another class), I assume it should be on the UI thread, based on the parent.
It can't be a background thread (you will get a warning when you change it to @WorkerThread
) , and it's rare to make it @AnyThread
too, because of possible breaking of what's in the parent class.
The IDE knows you should run it on the UI thread even if you didn't put the annotation, because the parent has it. See here:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = TextView(this)
thread {
test(textView)
}
}
@WorkerThread
fun test(textView: TextView) {
//you will get an IDE error/warning here:
FooEx().onBindView(textView)
}
open class Foo {
@UiThread
open fun onBindView(view: View) {
}
}
class FooEx : Foo() {
override fun onBindView(view: View) {
}
}
}
The new inspection could say "missing annotation based on parent", and the first quick-fix (which is the correct one in 99% of the times) would be to add what's on the parent. This annotation can help finding bugs later, as the annotation should match what's on the parent.
Suppose you have a class :
Each class that extends it, the annotation should be added to this function, and we should have an inspection for it.
And same thing for abstract/interface, of course, and for similar annotations.