What's the best way to implement around deprecated APIs in Android without over-suppressing warnings? This is really more a general Java question, but it keeps coming up in the Android context.
In Android (java) code, it is common for a feature or API to be deprecated and replaced with another option or implementation. The IDE and/or compiler (rightly) flags this with a warning. For example, the getParcelableExtra(String) API is deprecated as of API33 and we're encouraged to use getParcelabelExtra(String,Class).
So, if we have some code
someMethod(someTypeSomeArgs) {
...
someObj = intent.getParcelableExtra(EXTRA_STRING_PARAMETER)
...
}
It will generate a deprecation warning.
Since we're building for a variety of targets and the new API is often not available on an older platform, we can follow the documentation suggestions and use an SDK version check:
someMethod(someTypeSomeArgs) {
...
if (Build.VERSION.SDK_INT >= 33) {
someObj =intent.getParcelableExtra(EXTRA_STRING_PARAMETER,someClass);
} else {
someObj = intent.getParcelableExtra(EXTRA_STRING_PARAMETER);
}
...
}
This seems to be the recommended best practice for runtime, but the compiler warning is still there. We can suppress the compiler warning, but only at method scope, which works, but completely eliminates the ability to track deprecation at other locations in the method or track future deprecation while maintaining the code.
So...is there an accepted best practice for handling this?
Better create an extension function like ParcelableExt.kt
inline fun <reified T : Parcelable> Intent.parcelable(key: String): T? = when {
SDK_INT >= TIRAMISU -> getParcelableExtra(key, T::class.java)
else -> @Suppress("DEPRECATION") getParcelableExtra(key) as? T
}
inline fun <reified T : Parcelable> Bundle.parcelable(key: String): T? = when {
SDK_INT >= TIRAMISU -> getParcelable(key, T::class.java)
else -> @Suppress("DEPRECATION") getParcelable(key) as? T
}
inline fun <reified T : Parcelable> Bundle.parcelableArrayList(key: String): ArrayList<T>? = when {
SDK_INT >= TIRAMISU -> getParcelableArrayList(key, T::class.java)
else -> @Suppress("DEPRECATION") getParcelableArrayList(key)
}
inline fun <reified T : Parcelable> Intent.parcelableArrayList(key: String): ArrayList<T>? = when {
SDK_INT >= TIRAMISU -> getParcelableArrayListExtra(key, T::class.java)
else -> @Suppress("DEPRECATION") getParcelableArrayListExtra(key)
}
For example you can use this in you resultLauncher like this
result.data!!.parcelable(RESULT_KEY)