管理当前视图和 Class<?> 对象
Managing current View and Class<?> objects
我有一个应用程序范围的实用程序 class AppUtils,我可以在其中随时发布应用程序相关信息:
- 作为 SnackBar,当我在应用程序中时
- 或通过通知管理器
例如,当消息作为 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 模式大大提高当前代码的可维护性。订阅感兴趣的视图、活动、服务等中的特定事件将使您能够处理任意数量的通知,而无需明确跟踪其接收者。
这是这样工作的:
- 您在完全初始化后订阅每个感兴趣的组件中的事件。
- 接收并处理事件,可选地取消事件,如果组件认为其他组件不需要它。
- 组件不再需要事件时取消订阅(View为hidden/detached,Fragment被销毁,Activity为closed/minimized)。
这种方法的优点在于灵活性 — 您始终可以围绕每个事件添加更多逻辑,而不会影响订阅它的其他组件。此外,您可以为每个组件独立选择 subscribe/unsubscribe 的最佳时间(例如,可以随时发出通知,但只有在 Activity 可见并恢复时才应显示快餐栏)。
在您的应用中实现事件总线有多种不错的选择:
- Global Android broadcasts:最适合当你有多个高阶组件(活动、服务、广播接收器)时,对公共事件感兴趣。您可以使用 Intent 过滤器优先级和有序广播来中途取消事件处理。
- 本地广播管理器。非常简单,功能很少,但熟悉后也易于使用 API。
- Various specialized event bus libraries,选你最喜欢的。
- 各种 APIs,可以用作事件总线,即使这不是它们的主要目的:RxJava(我建议阅读 this article)、PendingIntents、ContentResolver.notifyUri 等.
我有一个应用程序范围的实用程序 class AppUtils,我可以在其中随时发布应用程序相关信息:
- 作为 SnackBar,当我在应用程序中时
- 或通过通知管理器
例如,当消息作为 Snackbar 运行时,我需要当前显示的视图容器的轨道才能在 Snackbar.make(view, text, length);
中使用它
当我想通过 NotificationManager.notify(int, Builder);
发布该消息时,我需要 here
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 模式大大提高当前代码的可维护性。订阅感兴趣的视图、活动、服务等中的特定事件将使您能够处理任意数量的通知,而无需明确跟踪其接收者。
这是这样工作的:
- 您在完全初始化后订阅每个感兴趣的组件中的事件。
- 接收并处理事件,可选地取消事件,如果组件认为其他组件不需要它。
- 组件不再需要事件时取消订阅(View为hidden/detached,Fragment被销毁,Activity为closed/minimized)。
这种方法的优点在于灵活性 — 您始终可以围绕每个事件添加更多逻辑,而不会影响订阅它的其他组件。此外,您可以为每个组件独立选择 subscribe/unsubscribe 的最佳时间(例如,可以随时发出通知,但只有在 Activity 可见并恢复时才应显示快餐栏)。
在您的应用中实现事件总线有多种不错的选择:
- Global Android broadcasts:最适合当你有多个高阶组件(活动、服务、广播接收器)时,对公共事件感兴趣。您可以使用 Intent 过滤器优先级和有序广播来中途取消事件处理。
- 本地广播管理器。非常简单,功能很少,但熟悉后也易于使用 API。
- Various specialized event bus libraries,选你最喜欢的。
- 各种 APIs,可以用作事件总线,即使这不是它们的主要目的:RxJava(我建议阅读 this article)、PendingIntents、ContentResolver.notifyUri 等.