如何在Android中的Activity之外调用getWindow()方法?

50

我想要整理我的代码并将重复的函数移动到一个单独的类中。 这行代码在扩展Activity的类中可以正常工作:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

然而,当我试图将它包含在外部类中时,它就无法正常工作。

我该如何从另一个类中调用getWindow()方法,并将其应用于一个Activity中?

7个回答

57

根据被接受的答案所建议的方法,您不应该保留引用。这种方法虽然可行,但可能会导致内存泄漏。

相反,您应该从您的视角使用以下方法:

((Activity) getContext()).getWindow()...

在您的视图中,您拥有对活动的托管引用,可以使用getContext()检索它。将其强制转换为Activity并使用来自活动的任何方法,例如getWindow()。


7
这是一些旧信息,但值得注意的是,有两种情况下此方法不适用。1)当上下文是应用程序上下文时(不会发生在视图内,但如果您在某种实用类中则需要知道)。2)偶尔视图上下文将解析为ContextThemeWrapper而不是活动。我还没有找到后者的原因,但需要记住这一点,因为它会导致类转换异常。 - Travis Castillo
从支持库23.3开始,不一定再起作用。ImageView上的getContext()返回一个TintContextWrapper,无法检索基本上下文。 - 0101100101
@0101100101 错了。你仍然可以通过将其转换为ContextWrapper来获取basecontext。 - Maxr1998
当然,没错,但是答案必须相应地更新。就这样 :) - 0101100101

52

在创建类时,传递活动的引用,并在调用相关方法时使用它。

void someMethodThatUsesActivity(Activity myActivityReference) {
    myActivityReference.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}

它完成了。非常感谢。 - Kalimah
14
这不应该被接受为答案,因为如果你没有清理所有手动创建的引用,它可能会导致内存泄漏。你应该始终使用 Android 提供的托管上下文。请看我的答案。 - Oliver Hausler
5
@OliverHausler - 我认为没有问题,因为没有人谈论保留对活动的引用。另外,您假设问题是关于从视图中调用它,而这并未在其中声明。最后一点是您假设上下文是活动,这并不一定正确。 - MByD
@MByD,看这个:http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html - 它清楚地说明“不要保留长期的对上下文活动的引用”。 - Oliver Hausler
5
我可能漏看了什么,但我没有看到任何参考资料被保留在这里。它被使用后立即丢弃(因为该方法已经结束)。 - MByD
MByD,即使您在使用后立即放弃引用,也会鼓励人们传递自己的上下文引用,这不是按照@Romain Guy和Google在Android平台上正确的做法。如果操作系统提供了对活动上下文的托管访问权限,我看不出为什么您应该这样做。这会产生混乱的代码,并违反最佳实践。 - Oliver Hausler

24
您可以使用以下方法将当前上下文转换为活动(activity):
/**
 * Get activity instance from desired context.
 */
public static Activity getActivity(Context context) {
    if (context == null) return null;
    if (context instanceof Activity) return (Activity) context;
    if (context instanceof ContextWrapper) return getActivity(((ContextWrapper)context).getBaseContext());
    return null;
}

然后你可以从活动中获取窗口。


3

Kotlin 代码:

myView.rootView.findViewById<View>(android.R.id.content).context as Activity

1
一个Window实例必须始终从ActivityDialog中检索。因此,正确的方法是通过依赖注入将Window引用传递给您的组件,然后确保您的组件不会超过Activity或Dialog的生命周期,以避免内存泄漏。

请注意,不能假设您总是可以通过查找View的Context来获取正确的Window,因为有时该View位于使用不同Window的Dialog内部。


0

在Android中,在Activity之外调用getWindow()方法,需要在该方法中传递Activity对象。例如,我设置了参数Activity,以便将某个Activity设置为全屏显示。

 public void fullScreen(Activity activity){
    activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    activity.getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}

然后当您使用它时,设置MainActivity.this参数

yourClassInstance.fullScreen(MainActivity.this);

-17

使用

getActivity().getWindow().requestFeature(Window.FEATURE_PROGRESS);

这将会更容易


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接