切换共享抽象父类的Activity时如何保留自定义对象数据?
我完全懂你现在的困扰:两个Activity共享同一个抽象父类,每次用startActivity()切换时,继承自抽象父类的自定义对象总会被重置,而且OnSavedInstanceState因为对象里包含LinkedList,序列化这条路走不通。下面给你几个实用的解决方案:
1. 用单例模式持久化对象
如果这个自定义对象不需要随Activity销毁而清除,单例是最直接的选择。你可以在抽象父类里或者单独的工具类中实现单例,用来持有这个对象:
public class CustomObjectHolder { private static MyCustomObject instance; // 私有构造方法防止外部实例化 private CustomObjectHolder() {} public static MyCustomObject getInstance() { if (instance == null) { instance = new MyCustomObject(); } return instance; } // 可选:如果需要主动清理对象,添加这个方法 public static void clearInstance() { instance = null; } }
之后在你的抽象父类里,直接通过CustomObjectHolder.getInstance()获取对象就行,不管怎么切换Activity,拿到的都是同一个实例,不会被重置。不过要注意:如果对象里持有Activity的Context这类引用,记得在不需要的时候调用clearInstance(),避免内存泄漏。
2. 让自定义对象实现Parcelable接口
OnSavedInstanceState用Serializable不行,但Android原生的Parcelable对LinkedList支持很好,而且序列化效率更高。给你的自定义对象实现Parcelable:
public class MyCustomObject extends AbstractParent implements Parcelable { private LinkedList<DataItem> dataList; // 构造方法、getter/setter等逻辑 // Parcelable核心实现 protected MyCustomObject(Parcel in) { dataList = in.readLinkedList(DataItem.class.getClassLoader()); } public static final Creator<MyCustomObject> CREATOR = new Creator<MyCustomObject>() { @Override public MyCustomObject createFromParcel(Parcel in) { return new MyCustomObject(in); } @Override public MyCustomObject[] newArray(int size) { return new MyCustomObject[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLinkedList(dataList); } }
然后在启动Activity时,把对象通过Intent传递:
Intent intent = new Intent(this, TargetActivity.class); intent.putExtra("CUSTOM_OBJECT_KEY", myCustomObject); startActivity(intent);
在目标Activity里获取对象:
MyCustomObject obj = getIntent().getParcelableExtra("CUSTOM_OBJECT_KEY");
这样切换时就能完整传递包含LinkedList的对象,不会出现重置问题。如果对象体积很大,频繁传递可能影响性能,这时候可以考虑其他方案。
3. 用ViewModel实现跨Activity数据共享
如果两个Activity关联紧密,ViewModel是Jetpack提供的专门解决组件间数据共享的方案,它的生命周期独立于Activity的临时销毁和配置变化:
先创建一个ViewModel类:
public class SharedDataViewModel extends ViewModel { private MutableLiveData<MyCustomObject> customObjectLiveData = new MutableLiveData<>(); public void updateCustomObject(MyCustomObject obj) { customObjectLiveData.setValue(obj); } public LiveData<MyCustomObject> getCustomObject() { return customObjectLiveData; } }
然后在两个Activity里获取同一个ViewModel实例:
// 在Activity中初始化并使用ViewModel SharedDataViewModel viewModel = new ViewModelProvider(this).get(SharedDataViewModel.class); // 设置对象 viewModel.updateCustomObject(myCustomObject); // 监听对象变化,自动更新逻辑 viewModel.getCustomObject().observe(this, updatedObj -> { // 这里处理拿到的最新对象 });
不管怎么切换Activity,ViewModel都会保留对象,而且不用担心内存泄漏——ViewModel会在Activity真正销毁时被系统自动清理。
4. 用自定义Application类存储全局对象
如果这个对象是全局业务需要的,可以把它存在自定义的Application类里:
public class MyApp extends Application { private MyCustomObject customObject; @Override public void onCreate() { super.onCreate(); customObject = new MyCustomObject(); } public MyCustomObject getCustomObject() { return customObject; } public void setCustomObject(MyCustomObject customObject) { this.customObject = customObject; } }
记得在AndroidManifest.xml里配置这个Application:
<application android:name=".MyApp" ...> ... </application>
之后在Activity里获取对象:
MyCustomObject obj = ((MyApp) getApplicationContext()).getCustomObject();
这种方式和单例类似,但更符合Android的全局存储规范,同样要注意避免对象持有Activity引用导致内存泄漏。
内容的提问来源于stack exchange,提问作者Epicurean Segal

