public WorkerTask<I, P, R> observe(final LifecycleOwner owner, final Consumer<WorkerTaskEvent<I, P, R>> observer) {
        checkNoLifecycleReferences(observer, owner);
        synchronized (taskMutex) {
            final AtomicBoolean ownerActiveFlag = new AtomicBoolean(isLifecycleActive(owner));
            if (ownerActiveFlag.get()) {
                Log.d(logPraefix + " new observer for active owner, posting lastEvent (" + lastEvent + "): " + owner);
                postToListener(lastEvent, observer);
            }
            final Disposable listenerDisp = taskEventData.subscribe(event -> {
                if (ownerActiveFlag.get()) {
                    postToListener(event, observer);
                }
            });
            owner.getLifecycle().addObserver((LifecycleEventObserver) (o, event) -> {
                synchronized (taskMutex) {
                    if (event.getTargetState() == Lifecycle.State.DESTROYED) {
                        Log.d(logPraefix + " owner destroyed, dispose listener for " + owner);
                        listenerDisp.dispose();
                        checkTaskDisposal();
                        return;
                    }
                    final boolean isActive = isLifecycleActive(owner);
                    if (isActive && !ownerActiveFlag.get()) {
                        Log.d(logPraefix + " owner switched to active (lastEvent=" + lastEvent + "): " + owner);
                        postToListener(lastEvent, observer);
                    }
                    ownerActiveFlag.set(isActive);
                }
            });
        }
        return this;
    }
registers a generic lifecycle-bound observer. Observers will be auto-disposed when owner is destroyed
main/src/main/java/cgeo/geocaching/utils/workertask/WorkerTask.java