geterializableExtra和getParcelableExtra被弃用。什么是选择?

发布于 2025-02-06 16:10:41 字数 1708 浏览 3 评论 0 原文

我已经升级了 targetsdkversion compilesdkversion 33

我现在要警告告诉我 and 方法被弃用。

我从类,这两种方法确实被弃用。

该文档表明我使用新的 getSerializableExtra(name:clazz :) and getParcelableExtra(name:clazz :) 方法。

谁能帮助我使用新方法?

示例警告

  1. 警告对象

​i.sstatic.net/j4zvy.png“ rel =“ noreferrer”> “

I have upgraded targetSdkVersion and compileSdkVersion to 33.

I am now getting warnings telling me that the getSerializableExtra(name:) and getParcelableExtra(name:) methods are deprecated.

I checked and confirmed from the documentation in the Intent class that these two methods are indeed deprecated.

The documentation suggests that I use the new getSerializableExtra(name:clazz:) and getParcelableExtra(name:clazz:) methods instead.

Can anyone can help me use the new methods?

Example warnings

  1. Warning while getting an Object:

getSerializableExtra_Deprecated_Image

  1. Warning while getting a List or ArrayList:

getSerializableExtra_Deprecated_List_Image

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

亽野灬性zι浪 2025-02-13 16:10:41

这就是我使用的:

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
}

我也为 getParcelcelable 在这里要求添加到直接支持库

This is what I use:

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
}

I've also written the same for getParcelable here and requested this to be added to the Support libraries directly

风情万种。 2025-02-13 16:10:41

方法 t getSerializableExtra(string,class&lt; t&gt;)来自Android 33。
因此,您将使用IF块用于使用Android以下33以下的设备。

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
}

然后您可以在活动中使用它:

val myPOJOClass = getSerializable(this, "my_intent_key", MyPOJOClass::class.java)

method T getSerializableExtra(String, Class<T>) is introduced from android 33.
so you shoud use an if block for devices using android below 33.

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
}

and then you can use it in your activity like this:

val myPOJOClass = getSerializable(this, "my_intent_key", MyPOJOClass::class.java)
单身狗的梦 2025-02-13 16:10:41

对于我们仍然使用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;
}

For those of us who still use Java, this function does the trick:

@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;
}
心是晴朗的。 2025-02-13 16:10:41

但是, Mohamad Seyedi的答案做到了。但是,从 onActivityResult() 获得意图数据的情况下,这将失败。

我们无法在 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
}

用法:

val myPOJOClass = intent.getSerializable("my_intent_key", MyPOJOClass::class.java)

解决方案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
}

用法:

val myPOJOClass = getSerializable(intent, "my_intent_key", MyPOJOClass::class.java)

However, Mohamad Seyedi's answer did the job. But it fails in the case of getting intent data from onActivityResult().

We can't get data using Activity's intent inside onActivityResult(). Below are the solutions I got.

Solution 1: Using extension function:

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
}

Usage:

val myPOJOClass = intent.getSerializable("my_intent_key", MyPOJOClass::class.java)

Solution 2: Using regular function:

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
}

Usage:

val myPOJOClass = getSerializable(intent, "my_intent_key", MyPOJOClass::class.java)
故人如初 2025-02-13 16:10:41

扩展 rumit patel的答案,使用带有Refifif类型参数的内联函数,用法更简单。
请注意,我认为返回类型可取消使用,因为 !! 应该只用作最后一个度假胜地(或在来电侧)。

@Suppress("DEPRECATION")
inline fun <reified T : Serializable> Intent.getSerializable(key: String): T? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
        this.getSerializableExtra(key, T::class.java)
    else
        this.getSerializableExtra(key) as? T
}

@Suppress("DEPRECATION")
inline fun <reified T : Parcelable> Intent.getParcelable(key: String): T? {
    Timber.d("intentextras parce")
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        this.getParcelableExtra(key, T::class.java)
    } else {
        this.getParcelableExtra(key)
    }
}

@Suppress("DEPRECATION")
inline fun <reified T : Parcelable> Intent.getParcelableArrayList(key: String): ArrayList<T>? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        this.getParcelableArrayListExtra(key, T::class.java)
    } else {
        this.getParcelableArrayListExtra(key)
    }
}

用法:

val mode1: Mode = intent.getSerializable("key")
val mode2 = intent.getSerializable<Mode>("key")

Expanding upon Rumit Patel's answer, using an inline function with reified type parameter, usage is even simpler.
Note that I made the return type nullable, because !! should in my opinion only be used as a last resort (or at caller side).

@Suppress("DEPRECATION")
inline fun <reified T : Serializable> Intent.getSerializable(key: String): T? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
        this.getSerializableExtra(key, T::class.java)
    else
        this.getSerializableExtra(key) as? T
}

@Suppress("DEPRECATION")
inline fun <reified T : Parcelable> Intent.getParcelable(key: String): T? {
    Timber.d("intentextras parce")
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        this.getParcelableExtra(key, T::class.java)
    } else {
        this.getParcelableExtra(key)
    }
}

@Suppress("DEPRECATION")
inline fun <reified T : Parcelable> Intent.getParcelableArrayList(key: String): ArrayList<T>? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        this.getParcelableArrayListExtra(key, T::class.java)
    } else {
        this.getParcelableArrayListExtra(key)
    }
}

Usage:

val mode1: Mode = intent.getSerializable("key")
val mode2 = intent.getSerializable<Mode>("key")
因为看清所以看轻 2025-02-13 16:10:41

受穆罕默德(Mohamad)的回答的启发,您可以进行扩展名

fun <T : Serializable?> Bundle.getSerializableCompat(key: String, clazz: Class<T>): T {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) getSerializable(key, clazz)!! else (getSerializable(key) as T)
}

,并在这样的地方称呼它:

   arguments?.getSerializableCompat("my_key", MyClass::class.java)

Inspired by Mohamad's answer, you can do an extension

fun <T : Serializable?> Bundle.getSerializableCompat(key: String, clazz: Class<T>): T {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) getSerializable(key, clazz)!! else (getSerializable(key) as T)
}

and call it everywhere like this:

   arguments?.getSerializableCompat("my_key", MyClass::class.java)
叫思念不要吵 2025-02-13 16:10:41

直到自己还没有使用它。
正如文档所说,更新的方法为

t geterializableExtra(string,class&lt; t&gt;),因此您认为您可以按照以下方式使用它。

val myPOJOClass = intent.getSerializableExtra("my_intent_key", MyPOJOClass::class.java)

Haven't used it myself till yet .
As the doc says the updated method is

T getSerializableExtra(String, Class<T>) So you can use it as follows i think.

val myPOJOClass = intent.getSerializableExtra("my_intent_key", MyPOJOClass::class.java)
孤寂小茶 2025-02-13 16:10:41
val myPojoClass = getSerializable(intent, "key_name_here", MyPojoTypeClass::class.java)

然后,创建该功能

 private fun <T : Serializable?> getSerializable(intent: Intent, key: String, className: Class<T>): T {
        return if (Build.VERSION.SDK_INT >= 33)
            intent.getSerializableExtra(key, className)!!
        else
            intent.getSerializableExtra(key) as T
    }
val myPojoClass = getSerializable(intent, "key_name_here", MyPojoTypeClass::class.java)

then, create that function

 private fun <T : Serializable?> getSerializable(intent: Intent, key: String, className: Class<T>): T {
        return if (Build.VERSION.SDK_INT >= 33)
            intent.getSerializableExtra(key, className)!!
        else
            intent.getSerializableExtra(key) as T
    }
我不咬妳我踢妳 2025-02-13 16:10:41

将回答以包裹的回答。

由于我们已经有了序列化的良好答案,因此如果您感到 bundlecomapt intentCompat 版本, 您可以更长的时间创建这样的扩展名并使用

inline fun <reified T: Parcelable> Bundle.getParcel(key: String): T? =
    BundleCompat.getParcelable(this, key, T::class.java)

inline fun <reified T: Parcelable> Intent.getParcel(key: String): T? =
    IntentCompat.getParcelableExtra(this, key, T::class.java)

Since we already have good answers with Serializable, will answer in favour of Parcelable

If you feel BundleComapt and IntentCompat versions are longer you can create extensions like this and use

inline fun <reified T: Parcelable> Bundle.getParcel(key: String): T? =
    BundleCompat.getParcelable(this, key, T::class.java)

inline fun <reified T: Parcelable> Intent.getParcel(key: String): T? =
    IntentCompat.getParcelableExtra(this, key, T::class.java)
脱离于你 2025-02-13 16:10:41

您可以使用顶级函数来序列化参数

,但是我遇到了一个问题,序列化对象列表

您可以使用这种方式放置和获取序列化参数数据,

序列化的数组列表

因为列表不是可序列化的类,您需要将其转换为支持这些支持这些 函数用于序列化

 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
    }

,此方式将其处理列出对象的序列化列表

  class YourFragment: Fragment {

      private latinit var list: List<YourObject>


      fun newInstance(
           listOfYourObject: List<YourObject>
       ): YourFragment {

           val args = Bundle()
           val yourList= ArrayList<YourObject>()
           yourList.addAll(listOfYourObject)
           args.putSerializable(LIST_KEY, yourList)
        
           val fragment = YourFragment()
           fragment.arguments = args
           return fragment
       }

   }

,现在可以以这种方式序列化您的列表对象

   override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requireArguments().serializable<ArrayList<YourObject>>(LIST_KEY)?.let{
        list = it.toList()
    }
   
 }

   

You can use top functions to serialize arguments

but I had a problem serializing the List of object

You can use this way to put and get serialized argument data

Because List is not a Serializable Class, you need to convert it to Array List that supports serializable

These functions are used for serializable

 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
    }

and this way handle puts serialized List of objects

  class YourFragment: Fragment {

      private latinit var list: List<YourObject>


      fun newInstance(
           listOfYourObject: List<YourObject>
       ): YourFragment {

           val args = Bundle()
           val yourList= ArrayList<YourObject>()
           yourList.addAll(listOfYourObject)
           args.putSerializable(LIST_KEY, yourList)
        
           val fragment = YourFragment()
           fragment.arguments = args
           return fragment
       }

   }

and now can get serialize of your list object in this way

   override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requireArguments().serializable<ArrayList<YourObject>>(LIST_KEY)?.let{
        list = it.toList()
    }
   
 }

   
听你说爱我 2025-02-13 16:10:41

对此有一个兼容性效果:

BundleCompat.getSerializable(bundle, name, clazz)

捆绑包并不可取,因此意图。首先需要检查extras。

There is a compat funtion for this:

BundleCompat.getSerializable(bundle, name, clazz)

bundle isn't nullable so intent.extras need to be null checked first.

会发光的星星闪亮亮i 2025-02-13 16:10:41

bundlecompat

BundleCompat.getSerializable(myBundle, "MySerializableKey", MySerializable::class.java)
BundleCompat.getParcelable(myBundle, "MyParcelableKey", MyParcelable::class.java)

它将行为,以便

  • 在SDK 34及更高版本上,此方法调用新的 bundle.getXyz(key ,t :: class.java)
  • 则执行检查铸件。

在SDK 33及以下,此方法调用旧 bundle.getxyz(key),如果 key 不存在或不匹配预期类型, null 将返回。

There were compatibility functions added within BundleCompat:

BundleCompat.getSerializable(myBundle, "MySerializableKey", MySerializable::class.java)
BundleCompat.getParcelable(myBundle, "MyParcelableKey", MyParcelable::class.java)

It will behave so that

  • on SDK 34 and above, this method calls the new Bundle.getXYZ(key, T::class.java)
  • on SDK 33 and below, this method calls the old Bundle.getXYZ(key) and performs a checked cast

If the key does not exist or does not match the expected type, null is returned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文