在Android中使用静态方法?

4

我已经在 Android 上制作了一些应用程序,发现我经常使用静态方法。

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

    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() 来完成该活动。 - njzk2
我觉得你误解了我的意思。我上面发布的代码是一个名为PrefFragment的类,我正在调用另一个名为SettingsActivity的活动的静态方法来完成这个SettingsAcivity。 - zFr3eak
你正在尝试完成另一个活动?一个没有显示的活动?这不是一个好主意。毕竟,该活动可能已被系统销毁。 - njzk2
2个回答

4
在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怎么可能是SettingsActivity的一个实例? - zFr3eak
1
那么,SettingsActivity 不就是你用来创建片段的活动吗? Fragment.getActivity() 返回用于创建它的活动。 - lucian.pantelimon
啊,现在我明白了,谢谢!但是让我给你举另一个例子,这里我使用了一个静态方法,而你的解决方案行不通。在我的finishActivityWithResultOkey()方法中,我想调用AppWidgetProvider中的另一个静态方法,它会使用defaultSharedPreferences创建一个数据库,并通过Alarmmanager启动一个闹钟。如果没有AppWidgetProvider中的静态方法,我该如何做呢?谢谢... - zFr3eak
正如我所说,该解决方案涵盖了这个特定情况。它不是一个全面的解决方案,我怀疑是否有这样一个全面的解决方案。有些情况下,你只能使用static。我的答案依赖于Fragment.getActivity()方法,如果没有它就无法工作:)。此外,上面的评论可能适用于不同的问题,如果没有更详细的信息,很难在评论中回答它。 - lucian.pantelimon

3

你可以使用一个名为 Mirroring 的 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() - lucian.pantelimon
你在说什么? - user2001693
1
根据您的编辑,我已经取消了踩的操作(实际上将其改为了点赞,因为现在这是一个有效的答案)。在您的编辑之前,您在回答中使用的是“SettingsActivity”而不是“SettingsFragment”(在此处进行了修订:http://stackoverflow.com/posts/26534852/revisions)。 - lucian.pantelimon

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