android:如何将当前的ValueEventListener附加到Query?

时间:2017-08-30 06:33:19

标签: android firebase

我正在使用ValueEventListeners从Firebase数据库中检索数据。现在我想从Query中删除ValueEventListener。像这样:

query.removeEventListener(listener);

如果遇到异常,我想在实际删除之前检查监听器是否已添加到查询中。但是,我无法找到如何检查查询是否有"听众;我也无法获得附加到查询的当前侦听器。有可能这样做吗?

3 个答案:

答案 0 :(得分:2)

是的,确实如此。您需要使用以下代码:

if(listener != null) {
    query.removeEventListener(listener);
}

如果您的监听器不等于null,则表示已经附加了,您需要将其删除,否则您不应该做任何事情。

请注意,您需要根据活动的生命周期删除侦听器。

根据Query class offical documentation,没有获取查询侦听器的方法。添加侦听器后,只需将其删除即可。您无法检查作为参数传递的侦听器的状态。

答案 1 :(得分:1)

您无法获取已添加的侦听器列表,因此您需要跟踪它们,但您可以安全地调用query.removeEventListener(侦听器)。如果没有附加给定的监听器,则不会发生任何事情。

请记住,您需要手动删除附加到DatabaseReference的所有侦听器,否则它们将被触发。

答案 2 :(得分:0)

Firebase博客中的某处建议使用另一种方法。随着时间的推移,我对其进行了一些修改,但是它确实允许您根据op的请求获取活动监听器的状态。有关其他功能,请参见代码注释。

像平常一样创建数据库引用和ValueEventListener。 使用此类为您附加和分离它们。我添加了一个getListenerState()方法。

将此类实例化为您的侦听器,并传入(DatabasReference, ValueEventListener)(Query, ValueEventListener),无论您使用的是哪个。

然后您可以致电:
changeListenerState(boolean activeState)更改侦听器状态。 getListenerState()可以获取已将此类附加到的所有侦听器的侦听器状态。

/**
 * Used to attach and detach listeners to DatabaseReferences and Queries. Adds a 2 second
 * delay when a listener is removed to prevent unnecessary re-querying due to configuration changes
 * etc.
 */
public class DataListenerPending {

private static final String TAG = "DataListenerPending";

private final Handler mHandler = new Handler();
private final Query mQuery;
private final ValueEventListener mListener;
private boolean mListenerRemovePending = false;
private boolean mListenerState = false;

private final Runnable mRemoveListener = new Runnable() {
    @Override
    public void run() {
        mQuery.removeEventListener(mListener);
        mListenerRemovePending = false;
        mListenerState = false;
    }
};

/**
 * @param query A reference to the query object from which the data is derived. It is used
 *              by this class to attach and detach the listener.
 * @param listener the listener to attach to this query.
 */
public DataListenerPending(Query query, ValueEventListener listener) {
    this.mQuery = query;
    this.mListener = listener;
}

/**
 * @param reference A reference to the query object from which the data is derived.
 *                          It is used by this class to attach and detach the listener.
 * @param listener The listener to attach to this reference.
 */
public DataListenerPending(DatabaseReference reference, ValueEventListener listener) {
    this.mQuery = reference;
    this.mListener = listener;
}

/**
 * Adds and removes the listener when called
 * @param attachState true to add a listener, false to remove it.
 */
public void changeListenerState(boolean attachState) {
    if (attachState) {
        if (mListenerRemovePending) {
            // If asked to attach listener and it is currently in a state of pending removal,
            // stop it from being removed.
            mHandler.removeCallbacks(mRemoveListener);
        } else {
            // Only attach listener if it is not already attached.
            if (!mListenerState) {
                mQuery.addValueEventListener(mListener);
                mListenerState = true;
            }
        }
        mListenerRemovePending = false;
    } else {
        // Request to remove listener received. Wait for 2 secs to account for config changes.
        mHandler.postDelayed(mRemoveListener, 2000);
        mListenerRemovePending = true;
    }
}

public boolean getListenerState() {
    return mListenerState;
}

}