我认为我没有正确实现ListenerRegistration

时间:2018-11-12 20:51:47

标签: android firebase google-cloud-firestore

我有一个聊天活动,该聊天活动使用Firebase查询从反向RecyclerView的底部到顶部按降序加载聊天室的5条最新消息。加载这些消息后发送到Firebase集合的消息通过更改位置显示在屏幕底部,方法是在调用onEvent之后将新列表项插入到列表中。这是我的代码:

private void initRecyclerView() {

        //initializes and sets adapter/resets variables


        mAdapter = new ChatRecyclerViewAdapter(mMessages);
        mRecyclerView.setAdapter(mAdapter);
        firstEventListenerCalled = false;


            final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
            linearLayoutManager.setReverseLayout(true);
            mRecyclerView.setLayoutManager(linearLayoutManager);


            Query query = mCollection.orderBy("timestamp", Query.Direction.DESCENDING).limit(5;

            firstRegistration = query.addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
                    Log.d("First SnapshotListener", "Called");

                    for (DocumentChange documentChange : queryDocumentSnapshots.getDocumentChanges()) {
                        switch (documentChange.getType()) {
                            case ADDED:

                                //Creates listener for queried messages that puts messages retrieved during initial query at end of message list,
                                // then another one after one runs its course that puts new ones at the beginning of the list
                                if (!firstEventListenerCalled) {

                                    Message message = documentChange.getDocument().toObject(Message.class);

                                    mMessages.add(message);

                                    mAdapter.notifyDataSetChanged();

                                } else if (firstEventListenerCalled) {

                                    Message message = documentChange.getDocument().toObject(Message.class);
                                    mMessages.add(0, message);
                                    mAdapter.notifyDataSetChanged();
                                    Log.d(TAG, "newMessageAdded " + message.getMessage());
                                }


                        }
                    }

                    firstEventListenerCalled = true;

                }
            });

我试图在活动的ListenerRegistration方法中删除onStop(),在RecyclerView方法中清除onRestart()的内容,然后重新调用该方法onStart()中的上述内容,这样在活动停止时不会有任何消息进入,并且在活动重新启动时,initRecyclerView()方法所查询的5条消息中出现的这段时间内发送的任何消息都将出现:

@Override
    protected void onRestart() {
        super.onRestart();
        mMessages.clear();
        mAdapter.notifyItemRangeRemoved(0, mMessages.size());
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart Called");
        initRecyclerView();

    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop Called");
        firstRegistration.remove();

        if (refreshRegistraton != null) {
            refreshRegistraton.remove();
        }
    }

    @Override
    public void onBackPressed() {
        finish();

    }

但是,使用此策略重新启动活动时,会发生以下情况:

  1. 5条查询消息以正确的顺序显示
  2. 在活动停止期间发送的所有消息除了这5条消息以外,还会以相反的顺序出现:

    • 旧邮件1

    • 旧邮件2

    • 旧邮件3

    • 旧邮件4

    • 旧邮件5

    • 停止时发送的消息2

    • 停止时发送的消息1

新消息似乎按照firstEventListenerCalled == true时描述的顺序加载,但是每次调用initRecyclerView()方法时,它就被设置为false。因为我删除了侦听器并完全重新创建了RecyclerView,所以根本不应单独加载它们。我想念什么?

1 个答案:

答案 0 :(得分:0)

看来,默认情况下为Android启用的disk persistance是造成此问题的原因。关闭它可以得到我想要的结果。