Управление текущим представлением и объектами класса

у меня есть App-wide utility class AppUtils, где я могу публиковать соответствующую информацию о приложении в любом случае:

  1. либо как закусочная, когда я нахожусь в приложении
  2. или с помощью диспетчера уведомлений

например, когда mesaages собирается как Snackbar мне нужен трек текущего отображаемого контейнера представления, чтобы использовать его в Snackbar.make(view, text, length); Когда я хочу опубликовать это сообщение с помощью NotificationManager.notify(int, Builder); и мне нужна подпись класс здесь

Intent resultIntent = new Intent(this, ResultActivity.class);
у меня в AppUtils:
public static void setCurrentViewAndClass(View v, Class<?> c)
{
    view = v; // view is static
    cls = c;  // cls is static
}

где я могу вспомнить отовсюду в моем проекте текущее представление (для параметра Snackbar) и cls (для намерения уведомления).

далее, я очищаю эти параметры, например, когда я оставляю приложение в фоновом режиме:

public static void clearCurrentViewAndClass()
{
    view = null;
    cls = null;
}

A. Когда эти параметры не null, я знаю, что мое приложение имеет фокус с соответствующим видом и я могу показать соответствующее сообщение в закусочной. B. Когда эти параметры являются null, я знаю, что мое приложение работает в фоновом режиме и я хочу показать соответствующее сообщение в качестве уведомления

поэтому всякий раз, когда фрагмент / действие создается или возобновляется, я вызываю setClassAndview() в каждом onResume() помнить параметры.

есть ли более элегантный способ отслеживать текущую отображаемую активность или активный класс ?

3 ответов


в качестве примера... создайте класс приложения (MyApp), зарегистрированный в AndroidManifest:

<application
        android:name=".MyApp"
        ...>

в классе приложений MyApp.onCreate () set:

registerActivityLifecycleCallbacks(new MyAppActivityLifecycleCallbacks());

в MyApp создайте статическое поле, которое содержит количество видимых действий и метод для определения, находится ли приложение на переднем плане или нет:

private static int mActivityCount = 0;

public static boolean isAppInForeground() {
    return mActivityCount != 0;
}

и, наконец, настройте класс ActivityLifecycleCallbacks для подсчета видимых действий:

private static final class MyAppActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {

        public void onActivityCreated(Activity activity, Bundle bundle) {
            // No operations
        }

        public void onActivityDestroyed(Activity activity) {
            // No operations
        }

        public void onActivityPaused(Activity activity) {
            // No operations
        }

        public void onActivityResumed(Activity activity) {
            // No operations
        }

        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            // No operations
        }

        public void onActivityStarted(Activity activity) {
            mActivityCount++;
        }

        public void onActivityStopped(Activity activity) {
            mActivityCount--;
        }
    }

и теперь вы можете позвонить MyApp.isAppInForeground (), чтобы определить, находятся ли какие-либо из ваших действий на переднем плане. Если вам нужна ссылка на текущую видимую активность, вы также можете справиться с этим здесь.


вы можете использовать ActivityManager для получения текущей деятельности.

эта ссылка объясняет, как.

однако, вы не можете получить текущий фрагмент, так как там может быть несколько фрагментов одновременно. Вы можете найти текущий фрагмент в определенной ViewGroup с помощью FragmentManager.

getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);

Это не совсем то, что вы просили, но вы можете значительно улучшить ремонтопригодность вашего текущего кода с помощью автобусная событие узор. Подписавшись на определенные события в заинтересованные взгляды, деятельность, предоставление услуг и т. д. позволит вам обрабатывать любое количество уведомлений без явного отслеживания их получателей.

это работает следующим образом:

  1. вы подписываетесь на события в каждом заинтересованном компоненте после того, как он полностью инициализированный.
  2. получить и обработать событие, при необходимости отменить событие, если компонент думает, что другим компонентам это не нужно.
  3. Отменить подписку, когда компоненту больше не нужны события (вид скрыт/отсоединен, фрагмент уничтожен, активность закрыта/свернута).

красота этого подхода заключается в гибкости - вы всегда можете добавить больше логики вокруг каждого события, не затрагивая другие компоненты, которые на него подписаться. Кроме того, вы можете выбрать лучшее время для подписки/отмены подписки независимо для каждого компонента (например, уведомления могут быть отправлены в любое время, но snackbars должны отображаться только тогда, когда активность видна и возобновлена).

есть несколько хороших вариантов для реализации шину событий в вашем приложении:

  1. глобальные трансляции Android: лучше всего подходит, когда у вас есть несколько компонентов высокого порядка (деятельность, услуги, широковещательные приемники), заинтересованы в общих чертах. Вы можете использовать приоритеты фильтра намерений и упорядоченные трансляции для отмены обработки событий на полпути.
  2. LocalBroadcastManager. Мертвый простой, несколько функций, но также прост в использовании со знакомым API.
  3. различные специализированные библиотеки шин событий, выберите вас любимый.
  4. различные API, которые могут использоваться в качестве шин событий, даже если это не их основная цель :RxJava (я рекомендую читать в этой статье), PendingIntents, ContentResolver.notifyUri и т. д.