在Couchbase Lite中删除了Document.ChangeListener

时间:2017-02-23 10:35:41

标签: android couchbase couchbase-lite changelistener

我正在使用Couchbase Lite和Android。我有一个文档,我需要添加一个Document.ChangeListener(每当这个文档发生更改时更新UI)。

我添加它但它似乎被“自动”删除,我找不到原因。我有一个方法“attachDocumentChangeListener”,我称之为:

public void attachDocumentChangeListener(String documentId, final DocumentChangeListener<TData> listener) {
       getDefaultDatabase().getDocument(documentId).addChangeListener(listener);
}

我不再触摸我的设备了,我通过其他设备对文档进行了更新。这应该触发ChangeEvent但似乎不会发生。

我注意到,当文档更新时,文档没有ChangeListener(即使我之前添加了一个juste)。要检查ChangeListener何时被删除,我在removeChangeListener(ChangeListener changeListener)类的函数Document中添加了一个断点,但是从未调用过,并且字段changeListeners在修订版已更新。

我在changeListeners添加了另一个断点,一个现场观察点。以下是此断点配置的屏幕截图:

enter image description here

我重复了操作(用另一台设备更新了文档),但我没有看到任何内容,但显示ChangeListener的日志已被删除(不知道如何)

{com.couchbase.lite.Document@6.888}.changeListeners will be accessed at com.couchbase.lite.Document.addChangeListener(Document.java:169)
size : 0, ID : 8980450c-5ddb-4181-a7bf-3e162c67a68f
{com.couchbase.lite.Document@6.888}.changeListeners will be accessed at com.couchbase.lite.Document.addChangeListener(Document.java:169)
size : 1, ID : 8980450c-5ddb-4181-a7bf-3e162c67a68f
{com.couchbase.lite.Document@9.975}.changeListeners will be accessed at com.couchbase.lite.Document.addChangeListener(Document.java:169)
size : 0, ID : 8980450c-5ddb-4181-a7bf-3e162c67a68f
{com.couchbase.lite.Document@10.189}.changeListeners will be accessed at com.couchbase.lite.Document.revisionAdded(Document.java:598)
size : 0, ID : 8980450c-5ddb-4181-a7bf-3e162c67a68f
{com.couchbase.lite.Document@10.189}.changeListeners will be accessed at com.couchbase.lite.Document.revisionAdded(Document.java:598)
size : 0, ID : 8980450c-5ddb-4181-a7bf-3e162c67a68f

我们可以看到removeChangeListener从未被调用,但changeListeners大小已设置为0。

任何人都可以提供帮助吗?

2 个答案:

答案 0 :(得分:2)

Document.ChangeListenerDocument实例相关联。我相信可能会发生以下事情。

  1. 获取文档ID 8980450c-5ddb-4181-a7bf-3e162c67a68f的文档实例(Document@6.888)。
  2. 将Document.ChangeListener添加到文档实例。
  3. 发布文档实例(垃圾收集)。
  4. 获取具有相同文档ID的文档实例(Document@9.975)。
  5. 但是此实例没有Document.ChangeListener,并且无法通知更改。

答案 1 :(得分:0)

我没有发现为什么会这样,但我设法通过通过Database.ChangeListener而不是Document.ChangeListener监听更改来解决这个问题。当我调用attachDocumentChangeListener(Document.ChangeListener)时,我将监听器添加到Map<String,Document.ChangeListener>(关键文档ID)中,当文档更新时,它会通过Database.ChangeListener.changed()方法,这是我如何覆盖它:

@Override
public void changed(Database.ChangeEvent event) {
    for (DocumentChange change : event.getChanges()) {
        List<DocumentChangeListener> documentChangeListeners = this.documentChangeListeners.get(change.getDocumentId());
        if(documentChangeListeners != null){
            for (DocumentChangeListener changeListener : documentChangeListeners)
                changeListener.changed(change);
        }
    }
}

这是我的两种方法attachDocumentChangeListener()&amp; detachDocumentChangeListener()

public void attachDocumentChangeListener(String documentId, final DocumentChangeListener listener){
    List<DocumentChangeListener> documentChangeListeners = this.documentChangeListeners.get(documentId);
    if(documentChangeListeners == null)
        documentChangeListeners = new ArrayList<>();

    documentChangeListeners.add(listener);
    this.documentChangeListeners.put(documentId, documentChangeListeners);
}

public void detachDocumentChangeListener(@NonNull DocumentChangeListener listener){
    String documentId = listener.getDocumentId();
    List<DocumentChangeListener> documentChangeListeners = this.documentChangeListeners.get(documentId);
    if(documentChangeListeners != null){
        documentChangeListeners.remove(listener);
        if(documentChangeListeners.isEmpty())
            this.documentChangeListeners.remove(documentId);
        else
            this.documentChangeListeners.put(documentId, documentChangeListeners);
    }
}

这3种方法都在Singleton中。