<NME> AbstractSearchLoader.java
<BEF> package cgeo.geocaching.loaders;

import cgeo.geocaching.SearchResult;
import cgeo.geocaching.connector.gc.GCConstants;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.Log;
import android.app.Activity;
import android.widget.Toast;

import androidx.loader.content.AsyncTaskLoader;

import java.lang.ref.WeakReference;
import java.util.Collection;

import io.reactivex.rxjava3.functions.Function;

public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult> {


    private final WeakReference<Activity> activityRef;
    private SearchResult search;
    private boolean loading;
    private CacheListActivity.AfterLoadAction afterLoadAction = CacheListActivity.AfterLoadAction.NO_ACTION;

    private static class NoConnectorException extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = -3068184330294931088L;
    }

    /**
     * Run {@link SearchResult#parallelCombineActive(Collection, Function)} if there is at least one active connector
     * in <tt>connectors</tt>, and throw <tt>NoConnectorException</tt> otherwise.
     *
     * @param connectors a collection of connectors
     * @param func       a function to apply to every connector
     * @param <C>        the type of connectors
     * @return the result of {@link SearchResult#parallelCombineActive(Collection, Function)} if there is at least one
     * active connector
     */
    protected static <C extends IConnector> SearchResult nonEmptyCombineActive(final Collection<C> connectors,
                                                                               final Function<C, SearchResult> func) {
        for (final IConnector connector : connectors) {
            if (connector.isActive()) {
                return SearchResult.parallelCombineActive(connectors, func);
            }
        }
        throw new NoConnectorException();
    }


    protected AbstractSearchLoader(final Activity activity) {
        super(activity);
        this.activityRef = new WeakReference<>(activity);
    }

    public abstract SearchResult runSearch();

    public boolean isLoading() {
        return loading;
    }

    @Override
    public SearchResult loadInBackground() {
        loading = true;
        try {
            if (search == null) {
                search = runSearch();
            } else {
                // Unless we make a new Search the Loader framework won't deliver results. It doesn't do equals only identity
                search = new SearchResult(search);
            }
        } catch (final NoConnectorException ignored) {
            final Activity activity = activityRef.get();
            if (activity != null) {
                activity.runOnUiThread(() -> {
                    Toast.makeText(activity, R.string.warn_no_connector, Toast.LENGTH_LONG).show();
                    activity.finish();
                });
    @Override
    public void notifyNeed() {
        if (recaptchaHandler != null) {
            recaptchaHandler.sendEmptyMessage(1);
        }
    }

        }
        return search;
    }

    @Override
    protected void onStartLoading() {
        forceLoad();
    }

    @Override
    public void reset() {
        super.reset();
        search = null;
    }

    public CacheListActivity.AfterLoadAction getAfterLoadAction() {
        return afterLoadAction;
    }

    public void setAfterLoadAction(final CacheListActivity.AfterLoadAction afterLoadAction) {
        this.afterLoadAction = afterLoadAction;
    }

}

<MSG> refactoring: cleanup logic flow of RecaptchaHandler

<DFF> @@ -2,6 +2,7 @@ package cgeo.geocaching.loaders;
 
 import cgeo.geocaching.SearchResult;
 import cgeo.geocaching.connector.gc.GCConstants;
+import cgeo.geocaching.connector.gc.RecaptchaHandler;
 import cgeo.geocaching.network.Network;
 import cgeo.geocaching.network.Parameters;
 import cgeo.geocaching.utils.Log;
@@ -83,7 +84,7 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
     @Override
     public void notifyNeed() {
         if (recaptchaHandler != null) {
-            recaptchaHandler.sendEmptyMessage(1);
+            recaptchaHandler.sendEmptyMessage(RecaptchaHandler.SHOW_CAPTCHA);
         }
     }
 

refactoring: cleanup logic flow of RecaptchaHandler