管理当前视图和 Class<?> 对象

Managing current View and Class<?> objects

我有一个应用程序范围的实用程序 class AppUtils,我可以在其中随时发布应用程序相关信息:

  1. 作为 SnackBar,当我在应用程序中时
  2. 或通过通知管理器

例如,当消息作为 Snackbar 运行时,我需要当前显示的视图容器的轨道才能在 Snackbar.make(view, text, length); 中使用它 当我想通过 NotificationManager.notify(int, Builder); 发布该消息时,我需要 here

中的 Class 签名
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;
}

一个。当这些参数为 NOT null 时,我知道我的应用程序具有相应视图的焦点,并且我可以将相关消息显示为 Snackbar。 B. 当这些参数为 null 时,我知道我的应用程序在后台,我想将相关消息显示为 Notification

因此,每当创建或恢复 Fragment/Activity 时,我都会在每个 onResume() 中调用 setClassAndview() 来记住参数。

是否有更优雅的方式来跟踪当前显示的 Activity 或活动的 Class?

您可以使用 ActivityManager 获取当前 Activity。

This link explains how.

但是,您无法获取当前Fragment,因为可能同时存在多个Fragment。您可以使用 FragmentManager 在特定的 ViewGroup 上找到当前片段。

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

例如...创建一个在 AndroidManifest 中注册的应用程序 class (MyApp):

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

在 MyApp 应用程序中 class.onCreate() 设置:

registerActivityLifecycleCallbacks(new MyAppActivityLifecycleCallbacks());

在 MyApp 中,创建一个静态字段,用于保存可见 Activity 的计数以及用于确定应用程序是否在前台的方法:

private static int mActivityCount = 0;

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

最后设置您的 ActivityLifecycleCallbacks class 以保持可见活动的计数:

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() 来确定您的任何 Activity 当前是否在前台。如果您需要对当前可见 Activity 的引用,您也可以在这里处理。

这并不完全符合您的要求,但您可以通过使用 event bus 模式大大提高当前代码的可维护性。订阅感兴趣的视图、活动、服务等中的特定事件将使您能够处理任意数量的通知,而无需明确跟踪其接收者。

这是这样工作的:

  1. 您在完全初始化后订阅每个感兴趣的组件中的事件。
  2. 接收并处理事件,可选地取消事件,如果组件认为其他组件不需要它。
  3. 组件不再需要事件时取消订阅(View为hidden/detached,Fragment被销毁,Activity为closed/minimized)。

这种方法的优点在于灵活性 — 您始终可以围绕每个事件添加更多逻辑,而不会影响订阅它的其他组件。此外,您可以为每个组件独立选择 subscribe/unsubscribe 的最佳时间(例如,可以随时发出通知,但只有在 Activity 可见并恢复时才应显示快餐栏)。

在您的应用中实现事件总线有多种不错的选择:

  1. Global Android broadcasts:最适合当你有多个高阶组件(活动、服务、广播接收器)时,对公共事件感兴趣。您可以使用 Intent 过滤器优先级和有序广播来中途取消事件处理。
  2. 本地广播管理器。非常简单,功能很少,但熟悉后也易于使用 API。
  3. Various specialized event bus libraries,选你最喜欢的。
  4. 各种 APIs,可以用作事件总线,即使这不是它们的主要目的:RxJava(我建议阅读 this article)、PendingIntents、ContentResolver.notifyUri 等.