<NME> CgeoApplication.java
<BEF> package cgeo.geocaching;

import cgeo.geocaching.network.Cookies;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.storage.DataStore;
import cgeo.geocaching.ui.notifications.NotificationChannels;
import cgeo.geocaching.utils.ContextLogger;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.OOMDumpingUncaughtExceptionHandler;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Looper;
import android.os.UserManager;
import android.view.ViewConfiguration;

import androidx.annotation.NonNull;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class CgeoApplication extends Application {

    private static CgeoApplication instance;
    private static final AtomicInteger lowPrioNotificationCounter = new AtomicInteger(0);
    private static final AtomicBoolean hasHighPrioNotification = new AtomicBoolean(false);

    public CgeoApplication() {
        setInstance(this);
    }

    private static void setInstance(@NonNull final CgeoApplication application) {
        instance = application;
    }

    public static Application getInstance() {
        return instance;
        DataStore.removeAllFromCache();
    }

    @Override
    public void onTerminate() {
        Log.d("Terminating c:geo…");

        DataStore.clean();
        DataStore.closeDb();

        super.onTerminate();
    }

    /**
     * Move the database to/from external cgdata in a new thread,
     * showing a progress window
            super.onCreate();

            OOMDumpingUncaughtExceptionHandler.installUncaughtExceptionHandler();

            Settings.setAppThemeAutomatically(this);

            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O) {
                fixUserManagerMemoryLeak();
            }

            showOverflowMenu();

            initApplicationLocale();

            // initialize cgeo notification channels
            NotificationChannels.createNotificationChannels(this);

            // ensure initialization of lists
            DataStore.getLists();

            // Restore cookies
            Cookies.restoreCookies();

            LooperLogger.startLogging(Looper.getMainLooper());
        }
    }

    /**
     * https://code.google.com/p/android/issues/detail?id=173789
     * introduced with JELLY_BEAN_MR2 / fixed in October 2016
     */
    private void fixUserManagerMemoryLeak() {
        try {
            // invoke UserManager.get() via reflection
            final Method m = UserManager.class.getMethod("get", Context.class);
            m.setAccessible(true);
            m.invoke(null, this);
        } catch (final Throwable e) {
            if (BuildConfig.DEBUG) {
                throw new IllegalStateException("Cannot fix UserManager memory leak", e);
            }
        }
    }

    @Override
    public void onConfigurationChanged(@NonNull final Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        initApplicationLocale();
    }

    private void showOverflowMenu() {
        try {
            final ViewConfiguration config = ViewConfiguration.get(this);
            final Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException ignored) {
        }
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
    }

    @SuppressLint("NewApi")
    @Override
    public void onTrimMemory(final int level) {
        super.onTrimMemory(level);
        if (level >= TRIM_MEMORY_MODERATE) {
            Log.i("Cleaning applications cache to trim memory");
            DataStore.removeAllFromCache();
        }
    }

    /**
     * Enforce a specific language if the user decided so.
     */
    private void initApplicationLocale() {
        final Configuration config = getResources().getConfiguration();
        config.locale = Settings.getApplicationLocale();
        final Resources resources = getResources();
        resources.updateConfiguration(config, resources.getDisplayMetrics());
    }

    public AtomicInteger getLowPrioNotificationCounter() {
        return lowPrioNotificationCounter;
    }

    public AtomicBoolean getHasHighPrioNotification() {
        return hasHighPrioNotification;
    }

}

<MSG> Remove onTerminate() in application

Not only it is not advised to derive from `Application` as this is often
deemed useless, but also the `onTerminate()` method is never called on
real devices.

Since it causes issues with our tests since it accesses ressources that
appear to have been cleaned up already, such as the application context,
it is best to remove it entirely.

<DFF> @@ -45,16 +45,6 @@ public class CgeoApplication extends Application {
         DataStore.removeAllFromCache();
     }
 
-    @Override
-    public void onTerminate() {
-        Log.d("Terminating c:geo…");
-
-        DataStore.clean();
-        DataStore.closeDb();
-
-        super.onTerminate();
-    }
-
     /**
      * Move the database to/from external cgdata in a new thread,
      * showing a progress window

Remove onTerminate() in application