【问题标题】:Does every object contained within a serialized object have to be serialized as well? (Android, Java)序列化对象中包含的每个对象是否也必须序列化? (安卓、Java)
【发布时间】:2020-10-09 00:40:57
【问题描述】:

我正在开发 Android Studio (Java),并将 Google Firebase 整合到我的项目中。在我的主要活动中,我实例化了一个 firebase 用户,并将所有相关信息存储在自定义“用户”类中。

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();
    }

}

我有一个多标签设置,其中每个标签都是一个片段。每个片段都需要访问代表当前登录用户的唯一用户对象,因此我将用户对象传递给每个片段。为了做到这一点,它需要被序列化,它就是这样。这是其中的一个片段:

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
    }
}

一切都很好!该选项卡可以访问存储在用户中的数据,我也可以做我需要的一切,直到应用程序最终进入后台。如果我的手机通过切换应用程序或拉下托盘或让屏幕休眠将应用程序置于后台,则应用程序崩溃并出现以下错误:

“Parcelable 在写入可序列化对象时遇到 IOException” . . . 引起:java.io.NotSerializableException: com.google.firebase.auth.internal.zzn

对我来说,这意味着 firebase auth 的部分也需要序列化。这是正确的解释吗?如果是这种情况,我觉得这将是一个很长的序列化兔子洞,如果它甚至可以序列化我不控制的类(并且不想改变)。有没有解决的办法?这样做的正确方法是什么?

感谢您的宝贵时间。

【问题讨论】:

    标签: java android firebase serialization firebase-authentication


    【解决方案1】:

    对我来说,这意味着 firebase auth 的部分也需要序列化。这是正确的解释吗?

    是的,如果你想用 Java 的内置序列化来序列化某些东西,它会尝试序列化所有嵌套的对象。正如您所发现的,使用 Firebase 对象并不是那么容易。它们根本不打算以这种方式序列化。

    您要序列化的数据对象最好只包含最基本的原始数据。它们不应包含更复杂的对象(尤其是那些本身没有实现Serializable 的对象)。实际上没有必要序列化 ​​FirebaseAuth,因为那是一个单例。而对于 FirebaseUser,您应该考虑仅从该对象中提取相关数据。

    【讨论】:

    • 谢谢,@DougStevenson(你在 Youtube 上有一些很棒的视频,所以也谢谢你!)!我想我可以在每个片段中调用 mAuth = FirebaseAuth.getInstance() ,如果有必要的话,这将达到同样的效果。在某些情况下,我也有可能只使用 UID,这将是可序列化的。回到代码!再次感谢!
    【解决方案2】:

    声明为transient 的字段不会被默认序列化机制序列化。

    Language spec, 8.3.1.3

    Serializable interface

    我想您因此可以使 FirebaseUser 和 FirebaseAuth 成员瞬态,同时“手动”提取您需要的任何部分。

    【讨论】:

    • 谢谢!也会对此进行调查!
    • 对于将来可能偶然发现此问题的任何人,我验证了此答案将起作用,将 Firebase 身份验证对象标记为我的用户对象中的瞬态实际上将防止可打包错误,这很棒!但是,我实际上可以按照上面 Doug 的回答进行重构,将 firebase 对象从我的用户对象中移出,这在我的情况下是更强大的解决方案。
    猜你喜欢
    • 2011-01-01
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    相关资源
    最近更新 更多