【发布时间】:2016-02-02 12:21:56
【问题描述】:
我有一个 TabLayout,在每个选项卡下都有一个 Fragment(我使用的是 ArrayPagerAdapter)。我注意到,当我从一个选项卡多次切换到另一个选项卡时,我的内存使用量会增加很多。从我的堆快照中,我可以看到有很多 AutoCompleteTextView 实例。
所以我确信问题可能出在此处:
public class MyFragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
final MultiAutoCompleteTextView eInput = (MultiAutoCompleteTextView) v.findViewById(R.id.TextInput);
EditorListener mEditorListener = new EditorListener();
eInput.setOnEditorActionListener(mEditorListener);
eInput.addTextChangedListener(new WhitespaceWatcher());
eInput.setAdapter(mDictionaryAdapter);
eInput.setTokenizer(new SpaceTokenizer());
...
}
...
class EditorListener implements TextView.OnEditorActionListener
{
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
...
MultiAutoCompleteTextView input = (MultiAutoCompleteTextView) textView.findViewById(R.id.TextInput);
...
}
}
...
}
但我不明白问题出在哪里。
【问题讨论】:
-
好吧,您加载的每个片段都会有一个
AutoCompleteTextView小部件。ArrayPagerAdapter的工作方式类似于FragmentPagerAdapter,因为所有页面都保存在内存中。 -
是的,我知道这一点。我的问题是 - 从我在 Android Studio 上的实例下可以看到 - 每次我切换选项卡时,都会出现一个 AutoCompleteTextView 的新实例。因此,如果我有 4 个选项卡并且我切换任何选项卡 4 次,我将获得 16 个 AutoCompleteTextView 实例。知道原因吗?谢谢。
-
您需要追踪创建这些实例的位置。例如,
onCreateView()是被调用 4 次还是 16 次?如果是后者,请追踪您创建片段实例的位置,并查看它们是否被调用了 4 次或 16 次。ArrayPagerAdapter中肯定有可能存在错误——例如,我从未将它与appcompat-v7一起使用,而且据我所知,这两者会因为一些意想不到的原因而产生不良交互。 -
onCreateView() 每次我切换到包含 Fragment 的选项卡,或者当我切换到它附近的一个选项卡时(距离 == 1)都会调用。片段的实例只有 4 个,应该如此。
-
好的,这实际上是预期的行为——至少,
FragmentPagerAdapter做同样的事情。这表明ArrayPagerAdapter没有错,这是一种解脱。理论上,参考树中显示的参考可以帮助您弄清楚AutoCompleteTextView上的内容,尽管我发现它们很难使用。您可以尝试使用LeakCanary,因为它往往会提供更集中的详细信息,说明可能的泄漏源。
标签: android-fragments memory-leaks android-widget commonsware