【问题标题】:Using static methods in Android?在 Android 中使用静态方法?
【发布时间】:2014-12-19 12:12:54
【问题描述】:

我已经在 Android 中制作了一些应用程序,并注意到我经常使用静态方法。

例如,我有一个扩展 PreferenceFragment 的类。在这个 PreferenceFragment 中,我在 Button 上设置了一个 onClick 事件。

    Button btn = new Button(getActivity().getApplicationContext());
    btn.setText("Save");
    v.addView(btn);
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            SettingsActivity.finishActivityWithResultOkey();            
        }
    });

然后我在我的SettingsActivity 中调用一个静态方法来完成这个Activity。这是做我想做的事的好方法吗?还是有更好的解决方案?

【问题讨论】:

  • 这不是一个好方法,因为完成一个活动的方法是一个实例方法。在您的情况下,您只需致电getActivity.finish() 即可完成活动
  • 我想你误会了我。我上面发布的代码是一个名为 PrefFragment 的类,我正在调用另一个名为 SettingsActivity 的活动的静态方法来完成这个 SettingsAcivity。
  • 您正在尝试完成另一项活动?一个不显示的?不是一个好主意。据您所知,该活动可能已经被系统破坏了。

标签: android static static-methods


【解决方案1】:

您可以使用称为镜像的 Java 属性。 下面我使用该属性来完成活动。

 Button btn = new Button(getActivity().getApplicationContext());
    btn.setText("Save");
    v.addView(btn);
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            SettingsFragment.this.getActivity().finish();            
        }
    });

【讨论】:

  • SettingsActivity.this.finish() 指的是封闭的Activity,它可能不存在(除非此代码放在Activity 中)。此外,如果代码在 Activity 中,则 finishActivityWithResultOkey 将在用作侦听器的匿名类中可用。提问者说他​​在Fragment 中有代码,因此为了使其工作,他可能必须从Fragment 中获取Activity,例如:MyFragmentClass.getActivity().finish()
  • 你在说什么
  • 我已根据您的编辑删除了反对票(实际上将其更改为赞成票,因为现在这是一个有效的答案)。在编辑之前,您在答案中使用SettingsActivity 而不是SettingsFragment(在此处修改:stackoverflow.com/posts/26534852/revisions
【解决方案2】:

在 Android 中(更准确地说,在 Java 等内存管理编程语言中),static 方法如果使用不当可能会导致“内存泄漏”。我引用了“内存泄漏”,因为它们不是内存泄漏的纯粹定义,例如在 C++ 中,您忘记从内存中删除某些项目并丢失对它们的引用(因此以后无法清除它们 - 至少不容易),但更像是在您不再需要引用时继续使用它们,并阻止 GC 为您清除内存。网上有很多文章涵盖了这个(搜索“Android静态内存泄漏”)和很多其他关于SO的问题已经被问到这个问题(见[static][Android][memory-leaks] tags),所以我不会进入这个。

对于您的特定情况,为了避免可能的内存泄漏,您可以使用 MyFragmentClass.this.getActivity() 从您的匿名 OnClickListener 对象绑定到的 Fragment 对象中获取 Activity,例如,SettingsActivity(就像这里的情况一样)并在上面调用.finishActivityWithResultOkey()。最好你也保护你的演员。

下面是代码的示例:

btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            final Activity activity = MyFragmentClass.this.getActivity();
            if(activity instanceof SettingsActivity)
               ((SettingsActivity)activity).finishActivityWithResultOkey();
            else
               throw new IllegalStateException("This OnClickListener requires a SettingsActivity to start the fragment containig it"); //helps with debugging
        }
    });

请注意:MyFragmentClass 指的是您将此代码放入的片段的类:)

【讨论】:

  • 我刚刚尝试了您的代码,它正在工作!但我不明白为什么! Activity 怎么可能是 SettingsAcivity 的实例?
  • 嗯,SettingsActivity 不是您用来创建片段的活动吗? Fragment.getActivity() 返回用于创建它的活动
  • 啊,是的,现在我明白了,谢谢!但是,让我向您展示另一个示例,其中我正在使用静态方法并且您的解决方案将不起作用。在我的finishActivityWithResultOkey() 方法中,我想在我的AppWidgetProvider 中调用另一个静态方法,该方法使用defaultSharedPreferences 创建一个数据库并通过Alarmmanager 启动一个警报。如果我的 AppWidgetProvider 中没有静态方法,我应该如何做到这一点?谢谢...
  • 正如我所说,解决方案涵盖了这个特殊情况。这不是一个全面的解决方案,我怀疑是否存在这样一个全面的解决方案。在某些情况下,您无法避免static。我的答案依赖于Fragment.getActivity() 方法,没有它就无法工作:)。此外,上面的评论可能适用于不同的问题,如果没有更详细的信息,很难在 cmets 中回答。
猜你喜欢
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
相关资源
最近更新 更多