java - Android什么时候序列化对象?

标签 java android android-fragments serialization pass-by-reference

我正在开发一个 Android 项目,我想将自定义类 MainActivityModel 传递给 FragmentMainActivityPlaceholderFragment

我已将 MainActivityModel 可序列化:

public class MainActivityModel implements Serializable{

    public int current = 0;
    public int pageCount = 0;

    public boolean pristine = true;

    // Stores the fetched dataMap
    public ArrayList<HashMap<String, String>> arrayList;

    public MainActivityModel() {
        this.arrayList = new ArrayList<>();
    }

    public String getCategory() {
        return Util.categories[current];
    }

    public CharSequence getmTitle () {
        return  Util.toTitleCase(
                Util.mapCategoryPretty(Util.categories[current]));
    }
}

我将它传递给Fragment,如下所示:

public static MainActivityPlaceholderFragment newInstance(MainActivityModel mainActivityModel) {
    MainActivityPlaceholderFragment fragment = new MainActivityPlaceholderFragment();
    Bundle args = new Bundle();
    args.putSerializable(ARG_DATA_MODEL, mainActivityModel);
    fragment.setArguments(args);
    Log.v(LOG_TAG, "Created: " + mainActivityModel.getmTitle());
    return fragment;
}

我像这样访问它:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mainActivityModel = (MainActivityModel) getArguments().getSerializable(ARG_DATA_MODEL);
    mMainActivityPlaceholderFragmentView = new MainActivityPlaceholderFragmentView(this, mainActivityModel);

    mCallbacks.onPlaceholderFragmentCreated(mainActivityModel.current);
}

我最初认为(在阅读下面我提到的答案后),序列化将数据转换为字节,并在需要时恢复它们。所以我的对象将被复制。如果我只想访问数据,这是可以的。但我还想修改 fragment 中的实际模型(在 MainActivity 中引用)。

为了进行实验,我在 Fragment 中将 pristine 设置为 false,并将其记录在 MainActivity 中,它确实是 false。

但是如果可序列化是按值传递的,那么这是如何发生的?

我读过的内容:

  1. What is object serialization?
  2. R: Pass by reference
  3. what is Serializable in Java
  4. What is serialization in Java?

最佳答案

Serialized 对象的引用仍然是对象引用,它与传递 List 对象或 Foo 对象没有什么不同。令人困惑的部分是序列化发生的if何处

来自 android.app.Fragment.setArguments(Bundle) 的文档:

The arguments supplied here will be retained across fragment destroy and creation.

有两种方法可以实现此目的:

  • 使 Bundle 仅存储原始字节,并为每个 get/put 操作进行序列化/反序列化。
  • 允许 Bundle 保存 Activity 对象,并在需要销毁/重新创建 fragment 时要求它序列化/反序列化所有内容。

显然,第一个选项非常效率低下:get/put 操作比 Activity/fragment 生命周期更改频繁得多。因此,Android 仅在生命周期发生变化时需要时进行序列化/反序列化。

这会导致您的用例出现“奇怪”的行为。您假设您的 Serialized 对象立即Bundle 序列化,而 Bundle 只是保存对您的目的。由于 fragment 在 newInstanceonCreate 调用之间不会被销毁,因此您会看到完全相同的 Bundle 包含完全相同的引用。

当然,您不应该依赖这些引用来保持完整。每当您的应用程序被要求保留其状态时(例如,当进入后台时、旋转屏幕时或当系统需要释放 RAM 时),这些对象都会被序列化,并且引用也会消失。这些对象将从序列化数据中重新创建,但它们将具有不同的引用。

关于java - Android什么时候序列化对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30935589/

相关文章:

java - Elasticsearch : Retrieve long text field from a document

java - Java中将时间分成相等的间隔

android - SupportLibrary 的目的

android-fragments - 没有主构造函数就不可能进行父类(super class)型初始化

java - 自定义注释不验证方法参数

java - 在多线程环境中使用 HttpClient 的最佳实践

android - 无法为 com.android.build.gradle.internal.api.ApplicationVariantImpl 类型的对象获取未知属性 'mergeResourcesProvider'

android - 如何在Android中播放手机内存中的音频文件

Android:对话框关闭后 ICS Webview 变白

android - 是什么导致 Google AdMob 泄露 ServiceConnection?