Android:由于成员变量导致内存泄漏?

时间:2014-10-28 08:31:34

标签: android memory-leaks

我开发了一个Android应用程序,它由FragmentActivity和几个片段组成,这些片段在制表符更改时调用。 每个片段都与一个视图相关联。片段的逻辑封装在单独的类中。这些课做了一些 复杂的计算。这些计算的结果将在片段视图的几个文本视图中显示。进一步的片段 view包含一个停止按钮,类的计算将在单击停止按钮时作出反应。

我现在的问题是如何在类中组织对这些视图成员(文本视图和停止按钮)的访问。安全吗? 将与每个文本视图关联的变量作为成员变量传递给相应的类?这是我使用的相应代码。

class ClassAFragment extends Fragment 
{
    ClassA classA;
    ...

    public View onCreateView(...) 
    {
        Button stopButton = (Button) this.getActivity().findViewById (R.id.btnStop);
        TextView timeLabel = (TextView) this.getActivity().findViewById (R.id.mTimeLabel);

        this.classA = new ClassA();
        this.classA.setAppElements(timeLabel, stopButton);
    }

    ...
}

class ClassA 
{
    TextView mTimeLabel;
    Button mStopButton;

    public void setAppElements(TextView timeLabel, Button stopButton) 
    {
        this.mTimeLabel = timeLabel;
        this.mStopButton = stopButton;

        this.mStopButton.setOnClickListener (this.mStopListener);
    }

    private void showCurrentProgress() 
    {
        this.mTimeLabel.setText("some text");
    }

    public void stop() 
    {
        // react upon stop button being clicked
    }

    OnClickListener mStopListener = new OnClickListener ()
    {
        @Override
        public void onClick (View v)
        {
            ClassA.this.stop ();
        }
    };

    ...
}

该代码在内存泄漏方面是否安全?在官方Android文档中,我读过你不应该这样做 将绑定到App上下文的任何对象传递给成员变量(Handling Runtime Changes)。

2 个答案:

答案 0 :(得分:1)

他们正在讨论如果在Fragment中使用setRetainInstance(true);并向其传递对与Context关联的任何其他对象的引用时可能遇到的问题。 setRetainInstance(true);表示在销毁Activity时不会销毁Fragment,因此如果向它传递对View的引用并销毁Activity,这将导致内存泄漏,因为View不会被垃圾回收。

答案 1 :(得分:1)

您可以使用LocalBroadcastManager或Bus(例如Otto EventBus)来通知UI(在您的情况下为Fragment)。 LocalBroadcastManager速度更快(但是,总线使用的是在ICS之前的Android版本中没有用的反射,并且可能会更慢),但总线更简单。希望它有所帮助。

P.S。永远不要在UI片段上放置setRetainInstance(true)。

P.P.S如果你这样做 - 确保在onDestroy()

中正确释放视图