【问题标题】:Multiple Realtime database calls through the onResume() Fragment lifecycle method通过 onResume() Fragment 生命周期方法调用多个实时数据库
【发布时间】:2021-05-14 03:01:42
【问题描述】:

我正在尝试创建一个涉及用户状态字段的应用程序。有 userStatus 和 customUserStatus。如果 customUserStatus 不为 null,则 userStatus 将设置为 customUserStatus 值,否则将设置为“在线”。这一切都发生在 onResume() 片段方法中。

我遇到的问题是 onResume() 的代码被多次调用......即使片段根本没有打开。

如您所见,onResume 代码被执行多次,多次设置用户状态。

(Chat Fragment exit)
    2021-02-10 11:59:34.828 22682-22682/com.user.myapp W/status: The chat fragment is no longer visible and the onStop has been called. Setting userStatus to offline

(ChatFragment opened)
    2021-02-10 11:59:34.866 22682-22682/com.user.myapp W/status: setting the user status to custom user status... At the Gym
    2021-02-10 11:59:34.868 22682-22682/com.user.myapp W/status: setting the user status to custom user status... At the Gym

(App exit - you can see that onResume() called multiple times...)
    2021-02-10 11:59:46.201 22682-22682/com.user.myapp W/status: Setting user status to offline in the MainActivity
    2021-02-10 11:59:46.260 22682-22682/com.user.myapp W/status: setting the user status to custom user status... At the Gym
    2021-02-10 11:59:46.262 22682-22682/com.user.myapp W/status: setting the user status to custom user status... At the Gym
    2021-02-10 11:59:46.263 22682-22682/com.user.myapp W/status: setting the user status to custom user status... At the Gym

我的 onResume 方法:

  1. 从数据库中获取用户对象
  2. 检查用户是否设置了自定义状态
  3. 如果不是,则将其状态设置为默认值 -> “在线”
  4. 否则,将其状态设置为 customStatus

我使用 onResume 来检查当前片段是否已打开,如果是,则它将设置用户的状态。我希望它只执行一次。

    @Override
    public void onResume() {
        super.onResume();
        //Log.w("status", "The chat fragment is now visible and the onResume has been called. Setting userStatus to online");

    String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(userId);
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            User user = snapshot.getValue(User.class);
            if(user.getCustomuserstatus() != null){
                if(user.getUserstatus() != user.getCustomuserstatus()){
                    setUserStatus(user.getCustomuserstatus());
                    Log.w("status", "setting the user status to custom user status... " + user.getCustomuserstatus());
                }
            } else {
                Toast.makeText(getActivity(), user.getCustomuserstatus(), Toast.LENGTH_SHORT).show();
                setUserStatus("online");
                Log.w("status", "setting the user status to online from the onresume");
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

【问题讨论】:

  • Firebase 实时数据库和 Cloud Firestore 是两个独立的数据库。请仅使用相关标签标记您的问题,不要同时使用两者。
  • 我认为answer 可能会有所帮助。

标签: android firebase-realtime-database firebase-authentication android-asynctask


【解决方案1】:

您无法控制 Android 调用 onResume 的频率。所以你的选择是:

  1. 跟踪您在onResume 中的代码是否已经使用更全局/静态的标志运行,并且仅在之前未运行时执行它。
  2. 删除onPause 中的侦听器,这样下次onResume 运行时,您将再次附加第一个侦听器。

我更喜欢第二种方法,因为它可以使代码更简洁,并且让数据库侦听器停留在用户不再查看的活动/片段上的可能性更小。

【讨论】:

    猜你喜欢
    • 2013-10-04
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多