我正在开发一个 Android 项目,我想将自定义类 MainActivityModel
传递给 Fragment
、MainActivityPlaceholderFragment
。
我已将 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。
但是如果可序列化是按值传递的,那么这是如何发生的?
我读过的内容:
最佳答案
对 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 在 newInstance
和 onCreate
调用之间不会被销毁,因此您会看到完全相同的 Bundle
包含完全相同的引用。
当然,您不应该依赖这些引用来保持完整。每当您的应用程序被要求保留其状态时(例如,当进入后台时、旋转屏幕时或当系统需要释放 RAM 时),这些对象都会被序列化,并且引用也会消失。这些对象将从序列化数据中重新创建,但它们将具有不同的引用。
关于java - Android什么时候序列化对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30935589/