【问题标题】:Why we need to serializable object for passing one activity to another activity in Android为什么我们需要序列化对象来将一个活动传递给 Android 中的另一个活动
【发布时间】:2018-07-13 08:25:31
【问题描述】:

谁能告诉我们为什么我们需要serializable对象来将一个活动传递给android中的另一个活动? Android 遵循 Java 语法。在java中,我们可以将对象传递给另一个类而无需序列化。

谢谢

【问题讨论】:

  • 当一个对象的状态需要保存一段时间后我们需要序列化对象来检索它。
  • 一般的 Java 序列化和 Android 的对象序列化并没有真正的区别。所以我推荐Oracle教程:java.sun.com/developer/onlineTraining/Programming/BasicJava2/…
  • 这里的所有答案都令人大开眼界,而且说得很好。我在几种情况下遇到过这个问题并阅读了类似的问题。 IMO,这是由Intent 的高级抽象引起的限制,当然需要一个解决方案。在大多数情况下,我们不需要编组相当简单的任务委派。我创建了一个包装器TrackedReference<Any>,它是可打包和可序列化的,无需对底层类型进行封送处理:stackoverflow.com/a/64944753/3405387

标签: java android


【解决方案1】:

在普通的java程序中传递参数(对象类型),是一种为对象创建一个新的处理程序并赋予另一个方法(在普通话中通过值传递引用)。

但是在 android 中,将对象引用从一个活动传递到另一个活动,它们的状态必须被持久化,这是一个非常令人头疼的问题。

您可以做的一种方法是在第一个活动中创建一个静态对象并从第二个活动中访问,尽管这似乎是一种最简单的方法,there is no guarantee that the system maintains the activity in the memory。因此,第二个活动可能会丢失对象引用。

其他方式,最推荐的方式是序列化(某种扁平化对象)对象并额外传递intent。在android中有两种序列化方式。

  1. 实现java的serializable接口
  2. 实现android的parcelable接口

但是,在 android 上,使用 serializable 会严重影响性能,解决方案是使用 parcelable。

你可以在here找到一个很好的关于android parcelable实现的教程和解释。

【讨论】:

  • 好的,由于对象引用是按值传递的,所以在之前的activity中,有可能会被android系统清除数据。因此,对象被写入流中,从而导致编组和取消编组。
  • 如果对象保存在静态字段中,则无论第一个活动的一个实例是否被销毁,它都会保存在内存中。因此它会起作用,实际上会起作用,因此是“内存泄漏”的来源。
【解决方案2】:

在得到答案之前,我们需要了解以下概念:

  • Android 使用Binder 进行进程间进程。即使是简单的应用程序也需要它,因为操作系统和应用程序在不同的进程中运行。
  • 编组: 将更高级别的应用程序数据结构转换为包裹以便嵌入到 Binder 事务中的过程
  • 解组 从通过活页夹交易接收的包裹重建更高级别的应用程序数据结构的过程。
  • 您可以将 Intents 视为 Binder 的更高级别抽象

基于documentation,以下是意图通信的发生方式:

  1. Activity A 创建一个带有动作描述的 Intent 并通过 它开始活动()。

  2. Android 系统在所有应用中搜索意图过滤器 符合意图。找到匹配项时,

  3. 系统通过调用启动匹配活动(活动 B) 它的 onCreate() 方法并将 Intent 传递给它。

为什么是 Parcelable 或 Serializable

IPC(进程间通信)要求对Intent 中的数据进行编组和取消编组。 Binder 为编组许多常见数据类型提供内置支持。但是,当我们定义自定义对象时,它会影响此过程,并且在此过程中收到的最终对象可能会损坏。

当您定义自定义对象时,您需要负责提供这种编组和解组,这是通过 Parcelable 和 Serializable 实现的(因为这两者之间的比较将是另一个话题,我不会在这里讨论太多)。这两者都提供了执行编组和解组的机制。这就是您需要使用 Parcelable 或 Serializable 的原因。

使用 Parcelable,您可以编写用于编组和解组对象的自定义代码,从而完全控制该过程。

Serializable 是一个标记接口,这意味着用户无法根据自己的要求对数据进行编组,并在 JVM 上完成,这不会给您任何控制权。

免责声明: 以上描述是我对基于某些方面的序列化需求背后的基本原理的理解 文档

【讨论】:

    【解决方案3】:

    你的问题基本上有两个问题,所以我们把它解耦。

    为什么在 Parcelable 中编组而不是直接传递对象引用?

    引用对象而不是编组/解组它们显然更快,内存效率更高。因此,当您可以直接传递对象时,您不应该使用 Parcelable。

    但是,在某些情况下您可能无法访问对象引用。

    • Intent 中,因为处理Intent 的进程可能不是发出Intent 的进程(这是一个进程间通信)
    • Activity 生命周期中,例如在onRestoreState() 中,因为当用户想要恢复它时,整个应用程序可能已被 memkiller 杀死。
    • Android 框架需要的任何其他地方

    在 IPC 中,为什么使用 Parcelable 而不是像 Java 那样使用 Serializable?

    那只是performance optimization

    【讨论】:

      【解决方案4】:

      如果我们想将对象从 Activity 传递到另一个 Activity 。我们需要保存传递​​状态。

      //to pass :
         intent.putExtra("MyClass", obj);  
      
      // to retrieve object in second Activity
      getIntent().getSerializableExtra("MyClass");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-10
        • 1970-01-01
        相关资源
        最近更新 更多