英文:
Does every object contained within a serialized object have to be serialized as well? (Android, Java)
问题
我正在使用Android Studio(Java)进行开发,并将Google Firebase集成到我的项目中。在我的主活动中,我实例化了一个Firebase用户,并将所有相关信息存储在自定义的“User”类中。
public class User implements Serializable {
FirebaseUser user;
FirebaseAuth mAuth;
String uid;
public User() {
System.out.println("Creating User");
mAuth = FirebaseAuth.getInstance();
user = mAuth.getCurrentUser();
uid = user.getUid();
}
}
我有一个多选项卡的设置,每个选项卡都是一个片段(fragment)。每个片段都需要访问表示当前登录用户的唯一用户对象,因此我将User对象传递给每个片段。为了实现这一点,它需要进行序列化,而它已经被序列化。以下是其中一个片段:
public class tab_list extends Fragment {
private static final String ARG_PARAM1 = "user_List";
private User user;
public tab_list() {
// 必需的空公共构造函数
}
public static tab_list newInstance(User u) {
tab_list fragment = new tab_list(); // 这将调用上面的空构造函数
Bundle args = new Bundle();
args.putSerializable(ARG_PARAM1, u);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
user = (User) getArguments().getSerializable(ARG_PARAM1);
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
// 进行操作
}
}
一切都运行得很好!该选项卡可以访问存储在user中的数据,并且我可以做我需要做的一切,直到应用程序进入后台。如果我的手机将应用程序放入后台,无论是通过切换应用程序还是下拉托盘或让屏幕进入休眠状态,应用程序都会崩溃,并显示以下错误:
“Parcelable encountered IOException writing serializable object”
.
.
.
Caused by: java.io.NotSerializableException: com.google.firebase.auth.internal.zzn
在我看来,这意味着Firebase认证的部分也需要被序列化。这个解释是否正确?我觉得如果是这样的话,这将是一个很长的序列化问题,而且如果要序列化我不能控制的类(我也不想更改这些类),那么可能会遇到问题。是否有办法避免这种情况?什么是正确的做法?
感谢您的时间。
英文:
I am working on Android Studio (Java), and have incorporated Google Firebase into my project. In my main activity, I instantiate a firebase user, and store all the relevant information in a custom "User" class.
public class User implements Serializable{
FirebaseUser user;
FirebaseAuth mAuth;
String uid;
public User()
{
System.out.println("Creating User");
mAuth = FirebaseAuth.getInstance();
user = mAuth.getCurrentUser();
uid = user.getUid();
}
}
I have a multi tab setup, where each tab is a fragment. Each fragment needs access to the lone user object representing the currently signed in user, so I pass the User object to each fragment. In order to do that, it needs to be serialized, which it is. Here is one of the fragments:
public class tab_list extends Fragment {
private static final String ARG_PARAM1 = "user_List";
private User user;
public tab_list() {
// Required empty public constructor
}
public static tab_list newInstance(User u) {
tab_list fragment = new tab_list(); // This calls the empty constructor above
Bundle args = new Bundle();
args.putSerializable(ARG_PARAM1, u);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
user = (User) getArguments().getSerializable(ARG_PARAM1);
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState){
//Do Stuff
}
}
Everything works great! The tab has access to the data stored in user, and I can do everything I need too, until the app ends up in the background. If my phone puts the app into the background, either by switching apps or pulling down the tray or letting the screen sleep, the app crashes and I get this error:
"Parcelable encountered IOException writing serializable object"
.
.
.
Caused by: java.io.NotSerializableException: com.google.firebase.auth.internal.zzn
To me, this implies that the parts of firebase auth ALSO need to be serialized. Is this the correct interpretation? I feel like this is going to be a long rabbit hole of serialization if that is the case, if it is even possible to serialize classes I don't control (and don't want to alter). Is there a way around this? What is the proper way to do this?
Thank you for your time.
答案1
得分: 1
> 对我来说,这意味着 Firebase 认证的这些部分也需要被序列化。这个解释正确吗?
是的,如果你想用 Java 的内置序列化来序列化某些东西,它会尝试序列化所有嵌套的对象。正如你所发现的,对于 Firebase 对象来说并不那么简单。它们根本就不是用这种方式来进行序列化的。
你希望被序列化的数据对象理想情况下应该只包含最基本、原始的数据。它们不应该包含更复杂的对象(特别是那些没有实现 Serializable
接口的对象)。没有必要对 FirebaseAuth 进行序列化,因为那是一个单例对象。而对于 FirebaseUser,你应该考虑只从该对象中提取出相关的数据。
英文:
> To me, this implies that the parts of firebase auth ALSO need to be serialized. Is this the correct interpretation?
Yes, if you want to serialize something with Java's built-in serialization, it will attempt to serialize all nested objects. As you're discovering, that's not really so easy with Firebase objects. They are simply not meant to be serialized this way.
Your data objects to be serialized should ideally contain only the most basic, raw data. They should not contain more complex objects (especially those that are not themselves implementing Serializable
). There is really no need to serialize FirebaseAuth, as that's a singleton. And you for FirebaseUser, you should consider pulling out only the relevant data from that object.
答案2
得分: 1
声明为transient
的字段不会被默认的序列化机制序列化。
我会认为你因此可以将FirebaseUser和FirebaseAuth成员声明为transient,同时'手动'提取你所需的任何部分。
英文:
Fields declared as transient
are not serialized by the default serialization mechanism.
I would suppose you can therefore make the FirebaseUser and FirebaseAuth members transient, while 'manually' extracting any parts of them you need.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论