片段 - 全局视图变量与本地和内部类侦听器以及内存泄漏

时间:2016-03-02 22:04:47

标签: android android-fragments view memory-leaks

假设考虑以下两个不同的定义;

全局变量1;

View mainView;
ListView categoryList;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater,  ViewGroup container,Bundle savedInstanceState) {
    mainView =  inflater.inflate(R.layout.fragment_expense_add,container,false);
    return mainView;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    categoryList = (ListView) mainView.findViewById(R.id.categoryList);
    categoryList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            catListAdapter.updateRadioButtons(position);
            if(amount.hasFocus())
                ((MainActivity)getActivity()).hideKeyboard();
        }
    });

本地

    Listview categoryList = (ListView) mainView.findViewById(R.id.categoryList);
    categoryList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            catListAdapter.updateRadioButtons(position);
            if(amount.hasFocus())
                ((MainActivity)getActivity()).hideKeyboard();
        }
    });

哪一种更能防止内存泄漏?

并且如上所示定义内部类触摸侦听器是否安全,例如项目单击侦听器?当我的片段被破坏时,它是否仍然引用它?如何避免内存泄漏?

3 个答案:

答案 0 :(得分:2)

如果您的变量是本地变量或成员变量,则没有区别。根据经验,如果您只需要特定方法中的变量,请将其置于该方法的本地(始终使用最小的范围)。

内部类适用于小方法,但对于较大的方法,可以创建成员变量或类来保持代码更清晰。

上面显示的代码不会泄露。

答案 1 :(得分:1)

这取决于您的片段是否保留。如果它被保留(我的意思是setRetainInstance(true);)那么你只需要确保你的片段在分离片段时没有引用外部Activity及其视图。

如果没有保留片段,那么您无需担心。 OnItemClickListener没有像片段或活动或线程那样的自己的生命周期。当片段被破坏时,所有相关的OnItemClickListener都将被销毁。

答案 2 :(得分:1)

在将内部类实例传递给具有自己生命周期的其他线程之前,您不应该害怕内存泄漏。 如果您需要这样做,只需创建一个静态内部类并将WeakReference传递给宿主片段/活动/无论如何。