Status Update
Comments
wi...@google.com <wi...@google.com> #2
Maybe also something aline the lines of:
inline fun <reified T> Bundle.parcelable(key: String): T? = when {
SDK_INT >= 33 -> getParcelable(key, T::class.java)
else -> @Suppress("DEPRECATION") getParcelable(key) as? T
}
ra...@gmail.com <ra...@gmail.com> #3
Over to platform owner for consideration.
ra...@gmail.com <ra...@gmail.com> #4
Yeah, we want this, but with
wi...@google.com <wi...@google.com> #5
also bugs me about Parcel.readParcelable
. if ya gonna nag me in a gazilion places through my code at least give me a nice way to resolve it. these 'blah is deprecated' msgs for code that works on my minSdkVersion just kill me. sticking an if or a supress on every second line of my code is just ...
a little comment about the above kotlin inline fun, I need both kotlin and java solution.
ra...@gmail.com <ra...@gmail.com> #6
Re #4, I think Google should offer this even if it's only going to work on U+ because right now the original APIs are deprecated and the replacements are not safe to use.
ap...@google.com <ap...@google.com> #7
wi...@google.com <wi...@google.com> #8
To add to #5, I went half an hour through the app, thinking the new method is backwards-compatible. Android Studio reported no issues, having the compileSdkVersion to 33 and minSdkVersion at 23.
Run the app on the device and boom, crash. Time to revert everything or replace every method with a backwards-compatbile function that I have to integrate on my own :(.
da...@allaboutapps.at <da...@allaboutapps.at> #9
gb...@jeniusbank.com <gb...@jeniusbank.com> #10
Can anyone tell me How to use the new declaration of the method
getParcelable(key, T::class.java)
and What's T class represent?
gb...@manubank.com <gb...@manubank.com> #11
So, before, you used this in Java:
(MyClass) getParcelable("someKey");
and this in Kotlin:
getParcelable("someKey") as MyClass
And now you could use this in Java:
getParcelable("someKey", MyClass.class);
And this in Kollin:
getParcelable("someKey", MyClass::class.java)
What's the point? I have no idea. Both produce the same things, and both will throw an exception in case of failure...
se...@gmail.com <se...@gmail.com> #12
@11 Sorry I didn't understand what class should I add in the second parameter, I used the old method like the following to save recycler view list state, what should I changed to make it with new method
@Suppress("DEPRECATION") override fun onResume() { super.onResume() val listState = mBundleRecyclerViewState.getParcelable<Parcelable>(recyclerStateKey) binding.homeRecyclerView.layoutManager?.onRestoreInstanceState(listState) }
kb...@jaguarlandrover.com <kb...@jaguarlandrover.com> #13
ca...@greenfly.com <ca...@greenfly.com> #14
wi...@google.com <wi...@google.com> #15
Branch: androidx-main
commit b0895cf4dc9a13b63d3d47aeb7b07a99cfc0bd28
Author: Hani Kazmi <hanikazmi@google.com>
Date: Mon Oct 17 16:59:50 2022
Add compat methods for new Bundle and Intent APIs
We have introduced new, safer, APIs for Parcel, Bundle and Intent in T
that we want to encourage developers to use. However the APIs have a bug
(
previously planned Compat methods that developers can use in all Andorid
versios, that will not use the T Apis until U where the bug is addressed.
There are subtle differences in the implementations of the platform
APIs, and so the behaviour of the compat methods:
1. Get Parcelable
public static <T> T getParcelable(@NonNull Bundle in, @Nullable String
key, @NonNull Class<T> clazz)
public static <T> T getParcelableExtra(@NonNull Intent in, @Nullable
String name, @NonNull Class<T> clazz)
These methods match the method signature and behaviour of the post-T,
type-safe APIs - return the value if it exists and is of the `clazz`
type, otherwise return null.
2. Get Collection
public static <T> ArrayList<T> getParcelableArrayList(@NonNull Bundle
in, @Nullable String key, @NonNull Class<? extends T> clazz)
public static <T> SparseArray<T> getSparseParcelableArray(@NonNull
Bundle in, @Nullable String key, @NonNull Class<? extends T> clazz)
public static <T> ArrayList<T> getParcelableArrayListExtra(@NonNull
Intent in, @Nullable String name, @NonNull Class<? extends T>clazz)
On these methods, the method signature matches the post-T APIs, but type
checking is only done on U+ devices, on first deserialisation. Checking
outside of this scenario requires a linear traversal of the array on each
call, and so is not done for performance (see
benchmarking shows a 400x difference for large arrays.
3. Get Array
public static Parcelable[] getParcelableArray(@NonNull Bundle in,
@Nullable String key, @NonNull Class<?> clazz)
public static Parcelable[] getParcelableArrayExtra(@NonNull Intent in,
@Nullable String name, @NonNull Class<?> clazz)
Due to Java generics erasure at runtime, the post-T method signature can
not be safely used on pre-U devices, as the pre-T platform APIs return a
Parcelable[] rather than T[], which can not be implicitely cast to a
subtype even if all items conform. The cost of manually casting is large
(see above). Therefore, we always return Parcelable[] on all device
versions, and we only type-check on U+ devices.
The ParcelCompat methods have been updated to match this behaviour. For
readArray, this is a source breaking API change. But
the current method signature would fail on any current devices if
assigned to anything other than an Object[] - succeeding
at compile time, but failing with a ClassCastException at runtime.
For readParcelableArray, it has been deprecated and replaced with
readParcelableArrayTyped, as updating the type signature would be a ABI
breaking change for libraries.
Bug: 242048899
Test: atest ParcelCompat BundleCompat IntentCompat on T and U devices
Test: Check binary compatibility manually with a test library.
Relnote: "Adds compatibility methods for new APIs introduced in Android
13 for Parcels, Bundles, and Intents.
Note: Some ParcelCompat method signatures have been updated, and may
require a source change on upgrade to confirm to the new signature."
Change-Id: I57e94c6efcc674173d201205fb175cef495bcf82
A core/core/api/current.ignore
M core/core/api/current.txt
M core/core/api/public_plus_experimental_current.txt
A core/core/api/restricted_current.ignore
M core/core/api/restricted_current.txt
M core/core/src/androidTest/java/androidx/core/content/IntentCompatTest.java
A core/core/src/androidTest/java/androidx/core/os/BundleCompatTest.java
M core/core/src/androidTest/java/androidx/core/os/ParcelCompatTest.java
M core/core/src/main/java/androidx/core/content/IntentCompat.java
A core/core/src/main/java/androidx/core/os/BundleCompat.java
M core/core/src/main/java/androidx/core/os/ParcelCompat.java
je...@veo.co <je...@veo.co> #16
Also, can you please offer extension functions for them? Maybe via another library?
Where can I reach these functions?
All in ParcelCompat?
wi...@google.com <wi...@google.com> #17
Can we also get BundleCompat.getSparseParcelableArray
and BundleCompat.getSerializable
? those methods are also deprecated (and buggy? ) in Android T.
al...@google.com <al...@google.com> #18
Could we add KTX functions for them?
Intent.kt
inline fun <reified T : Parcelable> Intent.parcelableExtra(key: String): T? =
IntentCompat.getParcelableExtra(this, key, T::class.java)
inline fun <reified T : Parcelable> Intent.parcelableArrayExtra(key: String): Array<T>? =
IntentCompat.getParcelableArrayExtra(this, key, T::class.java)
inline fun <reified T : Parcelable> Intent.parcelableArrayListExtra(key: String): ArrayList<T>? =
IntentCompat.getParcelableArrayListExtra(this, key, T::class.java)
inline fun <reified T : Serializable> Intent.serializableExtra(key: String): T? =
IntentCompat.getSerializableExtra(this, key, T::class.java)
Bundle.kt
inline fun <reified T : Parcelable> Bundle.parcelable(key: String): T? =
BundleCompat.getParcelable(this, key, T::class.java)
inline fun <reified T : Parcelable> Bundle.parcelableArray(key: String): Array<T>? =
BundleCompat.getParcelableArray(this, key, T::class.java)
inline fun <reified T : Parcelable> Bundle.parcelableArrayList(key: String): ArrayList<T>? =
BundleCompat.getParcelableArrayList(this, key, T::class.java)
inline fun <reified T : Parcelable> Bundle.sparseParcelableArray(key: String): SparseArray<T>? =
BundleCompat.getSparseParcelableArray(this, key, T::class.java)
inline fun <reified T : Serializable> Bundle.serializable(key: String): T? =
BundleCompat.getSerializable(this, key, T::class.java)
je...@veo.co <je...@veo.co> #19
I agree, KTX extensions would be a very nice addition as well.
wi...@google.com <wi...@google.com>
an...@gmail.com <an...@gmail.com> #20
ap...@google.com <ap...@google.com> #21
#15
wi...@google.com <wi...@google.com> #22
wi...@google.com <wi...@google.com> #23
wi...@google.com <wi...@google.com>
ru...@gmail.com <ru...@gmail.com> #24
ni...@flycatcherapps.com <ni...@flycatcherapps.com> #25
na...@google.com <na...@google.com> #26
ro...@gmail.com <ro...@gmail.com> #27
androidx.core:core-ktx:1.10.0 provides IntentCompat and BundleCompat
kotlin example: IntentCompat.getParcelableExtra(intent, "result", YourClass::class.java)
ro...@gmail.com <ro...@gmail.com> #28
wi...@google.com <wi...@google.com> #29
This should really be documented at
rh...@gmail.com <rh...@gmail.com> #30
Should this be marked as fixed with the new BundleCompat and IntentCompat APIs?
Description
Component used: SplashScreen Version used: 1.0.0-rc01 Devices/Android versions reproduced on: 100% Android 13
Artifact used: androidx.core:core-splashscreen Theme used: Theme.SplashScreen Crash Reproducible: False Devices/Android versions reproduced on: Pixel 4a (5G) (Android 13), Pixel 6/6 PRO
crash logs:
Fatal Exception: java.lang.NullPointerException at androidx.core.splashscreen.SplashScreenViewProvider$ViewImpl31.getIconView(SplashScreenViewProvider.kt:125) at androidx.core.splashscreen.SplashScreenViewProvider.getIconView(SplashScreenViewProvider.java:66) at fm.dice.splash.presentation.views.SplashActivity.triggerViewExitAnimation$lambda-0(SplashActivity.java:101) at fm.dice.discount.presentation.views.EventClaimCodeActivity$$InternalSyntheticLambda$2$e3b1050cf4cd59cef767f70a2238c7fe944dade6077bc18a7c181ca18936655c$0.onAnimationUpdate$bridge(EventClaimCodeActivity.java:9) at android.animation.ValueAnimator.animateValue(ValueAnimator.java:1653) at android.animation.ValueAnimator.setCurrentFraction(ValueAnimator.java:775) at android.animation.ValueAnimator.setCurrentPlayTime(ValueAnimator.java:738) at android.animation.ValueAnimator.start(ValueAnimator.java:1170) at android.animation.ValueAnimator.start(ValueAnimator.java:1189) at fm.dice.splash.presentation.views.SplashActivity.triggerViewExitAnimation(SplashActivity.java:117) at fm.dice.splash.presentation.views.SplashActivity.access$triggerViewExitAnimation(SplashActivity.java:49) at fm.dice.splash.presentation.views.SplashActivity$onCreate$1.onSplashScreenExit(SplashActivity.kt:83) at androidx.core.splashscreen.SplashScreen$Impl31.setOnExitAnimationListener$lambda-0(SplashScreen.kt:459) at androidx.core.splashscreen.SplashScreen$Impl31.$r8$lambda$_AQ1xSddL7-kLq4WrGTBd4lTQaY(SplashScreen.kt:29) at androidx.core.splashscreen.SplashScreen$Impl31$$InternalSyntheticLambda$1$761acc8e6019f840a6c78651dfd204d1aa5d02a4d0503ed9e876fedb200d42e5$0.onSplashScreenExit(SplashScreen.java:4) at android.window.SplashScreen$SplashScreenManagerGlobal.dispatchOnExitAnimation(SplashScreen.java:271) at android.window.SplashScreen$SplashScreenManagerGlobal.handOverSplashScreenView(SplashScreen.java:258) at android.app.ActivityThread.reportSplashscreenViewShown(ActivityThread.java:4147) at android.app.ActivityThread.lambda$syncTransferSplashscreenViewTransaction$1$android-app-ActivityThread(ActivityThread.java:4164) at android.app.ActivityThread$$ExternalSyntheticLambda5.run(ActivityThread.java:6) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239) at android.view.Choreographer.doCallbacks(Choreographer.java:899) at android.view.Choreographer.doFrame(Choreographer.java:827) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7898) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)