getSerializedExtra 和 getParcelableExtra 已弃用。还有什么选择呢?

Rum*_*tel 53 android android-intent kotlin deprecation-warning android-tiramisu

我已经升级到targetSdkVersion和。compileSdkVersion33

我现在收到警告,告诉我getSerializedExtra(name:)getParcelableExtra(name:)方法已被弃用。

我从Intent类中的文档检查并确认这两种方法确实已被弃用。

该文档建议我改用新的getSerializedExtra(name:clazz:)getParcelableExtra(name:clazz:)方法。

谁能帮助我使用新方法?

警告示例

  1. 收到以下警告时Object

getSerializedExtra_Deprecated_Image

  1. 收到Listor时发出警告ArrayList

getSerializedExtra_Deprecated_List_Image

Nik*_*las 68

这就是我使用的:

inline fun <reified T : Serializable> Bundle.serializable(key: String): T? = when {
  Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getSerializable(key, T::class.java)
  else -> @Suppress("DEPRECATION") getSerializable(key) as? T
}

inline fun <reified T : Serializable> Intent.serializable(key: String): T? = when {
  Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getSerializableExtra(key, T::class.java)
  else -> @Suppress("DEPRECATION") getSerializableExtra(key) as? T
}
Run Code Online (Sandbox Code Playgroud)

我还在这里为getParcelable编写了相同的内容,并请求将其直接添加到支持库中

  • 我们如何从意图中获取“ArrayList”? (3认同)
  • @Niklas您应该使用 Build.VERSION_CODES.TIRAMISU 而不是 33。此外,这是问题跟踪器上的一个请求,要求在支持库上提供此(以及 Parcelable ):https://issuetracker.google.com/issues/243986223 (3认同)

Moh*_*edi 21

该方法T getSerializableExtra(String, Class<T>)是从 android 33 开始引入的。因此,对于使用 android 33 以下的设备,您应该使用 if 块。

fun <T : Serializable?> getSerializable(activity: Activity, name: String, clazz: Class<T>): T
{
    return if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
               activity.intent.getSerializableExtra(name, clazz)!!
           else
               activity.intent.getSerializableExtra(name) as T
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在你的活动中使用它,如下所示:

val myPOJOClass = getSerializable(this, "my_intent_key", MyPOJOClass::class.java)
Run Code Online (Sandbox Code Playgroud)

  • 不管怎样,即使在版本检查之后,该方法已被弃用的烦人提示仍然无法让您安然入睡:) (8认同)

Rum*_*tel 6

然而,穆罕默德·赛耶迪的回答起到了作用。但在从 获取意图数据的情况下它会失败onActivityResult()

我们无法使用 Activity 内部的 Intent 来获取数据onActivityResult()。以下是我得到的解决方案。

解决方案1:使用扩展功能:

fun <T : Serializable?> Intent.getSerializable(key: String, m_class: Class<T>): T {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
        this.getSerializableExtra(key, m_class)!!
    else
        this.getSerializableExtra(key) as T
}
Run Code Online (Sandbox Code Playgroud)

用法:

val myPOJOClass = intent.getSerializable("my_intent_key", MyPOJOClass::class.java)
Run Code Online (Sandbox Code Playgroud)

解决方案2:使用常规函数:

fun <T : Serializable?> getSerializable(intent: Intent, key: String, m_class: Class<T>): T {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
        intent.getSerializableExtra(key, m_class)!!
    else
        intent.getSerializableExtra(key) as T
}
Run Code Online (Sandbox Code Playgroud)

用法:

val myPOJOClass = getSerializable(intent, "my_intent_key", MyPOJOClass::class.java)
Run Code Online (Sandbox Code Playgroud)


Dor*_*ani 5

对于我们这些仍然使用 Java 的人来说,这个函数可以解决问题:

@SuppressWarnings({"unchecked", "deprecation"})
@Nullable
public static <T extends Serializable> T getSerializable(@Nullable Bundle bundle, @Nullable String key, @NonNull Class<T> clazz) {
    if (bundle != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            return bundle.getSerializable(key, clazz);
        } else {
            try {
                return (T) bundle.getSerializable(key);
            } catch (Throwable ignored) {
            }
        }
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)