【问题标题】:Android: Should I pass in serializable or recreate the object from Bundle?Android:我应该传入可序列化的对象还是从 Bundle 重新创建对象?
【发布时间】:2015-05-02 08:45:27
【问题描述】:

所以我有一个 Calendar obj,它默认实现可序列化,我想将它传递到一个包中,以便它的值保存在屏幕旋转上。

我应该将它作为可序列化传递还是提取值并重新创建 obj 以提高效率?

bundle.putSerializable("key", calendar);

bundle.putInt("dayKey", calendar.get(Calendar.DAY_OF_MONTH));
bundle.putInt("monthKey", calendar.get(Calendar.MONTH));
bundle.putInt("yearKey", calendar.get(Calendar.YEAR));

【问题讨论】:

  • 我将使用 putSerializable。我不知道效率,但它更容易实现和阅读,而不是将对象分解成碎片。如果一个可序列化的对象有超过 10 个属性怎么办
  • 我会选择最简单和最不容易出错的可能性:bundle.putInt("time", calendar.getTime().getTime());

标签: java android serialization bundle


【解决方案1】:
  • onSaveInstanceState 方法用于存储 Activity 的状态。它会在您旋转屏幕按主页按钮或打开新通知栏的活动时调用。
  • 它在 onPause() 方法之后调用。
  • 您可以将自定义对象或任何原始数据类型(即称为活动的状态)保存为

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);        
        outState.putSerializable(KEY_CALENDAR, cal);        
    }
    
  • onRestoreInstanceState() 方法用于恢复活动的状态。

  • 在 onStart() 方法之后调用

  • 你可以像这样恢复Activity的状态

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);       
        cal = (Calendar) savedInstanceState.getSerializable(KEY_CALENDAR);
    }
    

    这里你可以使用serializable来保存Activity的状态。

  • 你也可以使用 onCreate() 方法来恢复你保存的状态,因为 bundle 在 onCreate() 和 onRestoreInstanceState() 方法中都是一样的

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); 
    
        if(savedInstanceState != null) {
            cal = (Calendar) savedInstanceState.getSerializable(KEY_CALENDAR);
        } else {
            cal = Calendar.getInstance();
            cal.setTime(new Date());    
        }
    }
    

【讨论】:

    【解决方案2】:

    使用Parcelable 而非Serializable。如果性能很重要,Parcelable 可能会快 10 倍左右 (http://www.developerphil.com/parcelable-vs-serializable/)

    此外,您可以使用https://github.com/johncarl81/parceler 来避免生成(和维护!)所有原本会存在的样板代码。

    @Parcel
    public class Person {
      ...
    }
    
    Parcelable parcelable = Parcels.wrap(new Person(..));
    Person = Parcels.unwrap(parcelable);
    

    【讨论】:

      【解决方案3】:

      老实说,虽然Parcelable 绝对是首选的序列化方法,但我认为对于这种情况,您只需将其作为Serializable 额外添加即可。考虑到重新创建Activity 所完成的工作量,我认为序列化Calendar 实例的费用可以忽略不计。

      如果不出意外,它会让您的代码更易于维护和简洁。

      【讨论】:

        【解决方案4】:

        Android不推荐使用Serializable;请改用Parcelable

        我猜这取决于Object 的大小以及手动重新创建的麻烦程度。

        【讨论】:

          猜你喜欢
          • 2012-07-07
          • 2019-09-23
          • 1970-01-01
          • 2011-09-09
          • 1970-01-01
          • 2012-07-15
          • 2023-03-22
          • 2017-10-30
          • 2012-01-16
          相关资源
          最近更新 更多