Odbiorniki powiadomień są wewnętrznie utrzymywane przez tę bibliotekę jako słabe odwołania, co oznacza, że musisz przechowywać twarde odniesienie zewnętrznie, aby nie były zbierane śmieci. Sprawdź wiersze 642–655 klasy BasicContext:
public void addNotificationListener(String name, String channelNameFilter, NotificationListener listener) {
name = nullToEmpty(name);
channelNameFilter = channelNameFilter != null ? channelNameFilter : ".*";
Pattern channelNameFilterPattern = Pattern.compile(channelNameFilter);
NotificationKey key = new NotificationKey(name, channelNameFilterPattern);
synchronized (notificationListeners) {
notificationListeners.put(key, new WeakReference<NotificationListener>(listener));
}
}
Jeśli GC odbierze twojego słuchacza, wywołania "get" na słabej referencji zwrócą wartość null i nie zostaną uruchomione, jak widać z linii 690 - 710
@Override
public synchronized void reportNotification(int processId, String channelName, String payload) {
Iterator<Map.Entry<NotificationKey, WeakReference<NotificationListener>>> iter = notificationListeners.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<NotificationKey, WeakReference<NotificationListener>> entry = iter.next();
NotificationListener listener = entry.getValue().get();
if (listener == null) {
iter.remove();
}
else if (entry.getKey().channelNameFilter.matcher(channelName).matches()) {
listener.notification(processId, channelName, payload);
}
}
}
Aby rozwiązać ten problem, dodaj swoje odbiorniki powiadomień jako takie:
/// Do not let this reference go out of scope!
PGNotificationListener listener = new PGNotificationListener() {
@Override
public void notification(int processId, String channelName, String payload) {
// interesting code
};
};
pgConnection.addNotificationListener(listener);
Moim zdaniem dość dziwny przypadek użycia słabych odniesień...