问题描述
简介:
我有一个应用程序,它具有以下结构:动作条向上顶(ActionBarSherlock)ViewPagerIndicator低于(制表符)ViewPager(主机片段)
I have an app which has the following structure:ActionBar up top (ActionBarSherlock)ViewPagerIndicator below that (for tabs)ViewPager (hosts Fragments)
我有一个问题,我的片段之一引起相当大的内存泄漏。我将问题范围缩小到下述情况:
I have a problem that one of my fragments is causing a rather major memory leak. I narrowed the problem down to the following case:
这是造成泄漏的片段,什么也不做,但膨胀的布局,在它的 onCreateView
方法。这样做是通过以下方式:
The fragment which is causing the leak does nothing but inflating a layout in it's onCreateView
method. This is done the following way:
return inflater.inflate(R.layout.filter_auctions_fragment, container, false);
并无异常。
布局文件只包含一个滚动型
,的LinearLayout
和两个的EditText
S在它(包括更一般的东西,但我将问题范围缩小到仅仅这些意见,使之简单)。
The layout file only includes a ScrollView
, LinearLayout
and two EditText
s in it (includes more normally stuff but i narrowed the problem down to just these views to make it simple).
现在的code这是我们用来添加片段: mTabsAdapter.addTab(TABNAME,ProblematicFragment.class);
Now the code that's used to add the fragment: mTabsAdapter.addTab(tabName, ProblematicFragment.class);
mTabsAdapter
是 TabsAdapter
的实例,扩展一个类 FragmentPagerAdapter 。这是相当标准的,所以我不包括源保持这个问题,越短越好。
mTabsAdapter
is an instance of TabsAdapter
, a class that extends FragmentPagerAdapter
of the support library. It's rather standard so I'm not including the source to keep this question as short as possible.
现在有趣的部分:
这是与堆发生了什么,当我转我的设备来回几次:
This is what happens with the heap when i rotate my device back and forth a few times:
12-28 12:26:27.180: D/dalvikvm(18841): GC_CONCURRENT freed 530K, 7% free 10701K/11436K, paused 4ms+7ms, total 58ms
12-28 12:26:27.180: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 24ms
12-28 12:26:28.270: D/dalvikvm(18841): GC_CONCURRENT freed 737K, 8% free 11048K/11964K, paused 4ms+5ms, total 53ms
12-28 12:26:29.510: D/dalvikvm(18841): GC_CONCURRENT freed 789K, 8% free 11464K/12436K, paused 5ms+5ms, total 42ms
12-28 12:26:30.640: D/dalvikvm(18841): GC_CONCURRENT freed 888K, 9% free 11919K/12984K, paused 4ms+5ms, total 52ms
12-28 12:26:31.810: D/dalvikvm(18841): GC_CONCURRENT freed 903K, 8% free 12421K/13500K, paused 3ms+8ms, total 58ms
12-28 12:26:33.800: D/dalvikvm(18841): GC_CONCURRENT freed 1092K, 9% free 13005K/14272K, paused 4ms+6ms, total 59ms
12-28 12:26:33.800: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 20ms
12-28 12:26:36.000: D/dalvikvm(18841): GC_CONCURRENT freed 1355K, 11% free 13518K/15048K, paused 3ms+8ms, total 74ms
12-28 12:26:36.000: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 19ms
12-28 12:26:38.110: D/dalvikvm(18841): GC_CONCURRENT freed 1450K, 11% free 14106K/15720K, paused 3ms+11ms, total 72ms
12-28 12:26:40.450: D/dalvikvm(18841): GC_CONCURRENT freed 1530K, 11% free 14807K/16516K, paused 2ms+15ms, total 75ms
12-28 12:26:40.450: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 29ms
12-28 12:26:43.030: D/dalvikvm(18841): GC_CONCURRENT freed 1682K, 11% free 15591K/17452K, paused 3ms+10ms, total 66ms
12-28 12:26:43.030: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 32ms
显然,内存泄漏。是的,我知道这会导致活动从地上爬起来重建,这就是我想要的,因为我有不同的布局风景和肖像模式。 Nontheless它应该不会造成内存泄漏。
Clearly, a memory leak.Yes, i know it causes the Activity to be recreated from the ground up and this is what I want because i have different layouts for landscape and portrait modes. Nontheless it shouldn't cause a memory leak.
我发现这个问题的根源。这是两个
的EditText
的,我前面提到的。当我从布局中删除他们,做同样的测试(来回转动)。这些都是GC的消息我得到:
I've found the source of this problem. It's the two
EditText
's that i mentioned earlier. As soon as i remove them from the layout and do the same test (rotate back and forth). These are the GC messages i get:
12-28 12:21:41.270: D/dalvikvm(17934): GC_CONCURRENT freed 534K, 7% free 10853K/11576K, paused 3ms+7ms, total 44ms
12-28 12:21:42.560: D/dalvikvm(17934): GC_CONCURRENT freed 818K, 9% free 11113K/12108K, paused 11ms+9ms, total 95ms
12-28 12:21:44.680: D/dalvikvm(17934): GC_CONCURRENT freed 1036K, 10% free 11313K/12528K, paused 3ms+6ms, total 54ms
12-28 12:21:44.680: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 15ms
12-28 12:21:47.420: D/dalvikvm(17934): GC_CONCURRENT freed 1089K, 10% free 11510K/12780K, paused 2ms+6ms, total 79ms
12-28 12:21:47.420: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 39ms
12-28 12:21:50.200: D/dalvikvm(17934): GC_CONCURRENT freed 1317K, 12% free 11461K/12956K, paused 4ms+13ms, total 84ms
12-28 12:21:53.210: D/dalvikvm(17934): GC_CONCURRENT freed 1629K, 14% free 11148K/12956K, paused 3ms+7ms, total 47ms
12-28 12:21:55.580: D/dalvikvm(17934): GC_CONCURRENT freed 1056K, 13% free 11302K/12956K, paused 4ms+7ms, total 59ms
12-28 12:21:57.280: D/dalvikvm(17934): GC_CONCURRENT freed 1306K, 14% free 11200K/12956K, paused 5ms+5ms, total 82ms
12-28 12:21:59.420: D/dalvikvm(17934): GC_CONCURRENT freed 1035K, 12% free 11408K/12956K, paused 3ms+7ms, total 55ms
12-28 12:22:01.990: D/dalvikvm(17934): GC_CONCURRENT freed 1392K, 13% free 11352K/12956K, paused 4ms+9ms, total 54ms
12-28 12:22:01.990: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 30ms
现在这就是我希望看到的!
Now that's what I want to see!
为什么!?
谁能告诉我为什么会这样?我想补充一点,我没有保持参照本
的EditText
对象的任何位置在我的应用程序(我通常做,但即使我删除了所有他们进行测试的目的泄漏仍然发生)。
Can someone tell my why this is happening? I would like to add that I'm not keeping a reference to these
EditText
object anywhere in my app (I normally do, but even when i removed all of them for testing purposes the leak still happens).
奖金 - 泄漏MAT截图:
正如你可以看到有该片段和活动的16个实例,同时也应该只有一个。
As you can see there are 16 instances of the Fragment AND the Activity, while there should be only one.
编辑:
我注意到,当我手动添加片段在不同的活动(使用
FragmentManager.beginTransaction()
)的泄漏不会发生!我完全糊涂了,现在......
I noticed that when i manually add the fragment in a different activity (using
FragmentManager.beginTransaction()
) the leak does not occur!!! I'm completely confused now...
EDIT2:
删除
安卓的
属性。但是现在他们是pretty的没用... 的EditText
取值修复它的ID
Removing the
android:id
attribute of the EditText
s fixes it... But now they're pretty useless...
推荐答案
我发现适合我的需求的解决方案。
I have found a solution that fits my needs.
我跟踪这个问题降低到
widget.EditableInputConnection
。我认为确实在建议系统中查找。它还负责保存到我的活动,从而导致内存泄漏。
I tracked the problem down to
widget.EditableInputConnection
. Which I think does the lookup in the suggestion system. It is also responsible for holding on to my Activity, hence causing a memory leak.
我不需要建议,所以我想将其关闭。然而它已被证明是困难的。
EditText.setInputType
没有工作,无论是在XML,也不code。
I do not need the suggestions so I wanted to turn it off. However it has proven to be difficult.
EditText.setInputType
did not work, neither in xml nor code.
我最后做以下。神奇的是发生在
onCreateInputConnection()
:
I ended up doing the following. The magic is happening in
onCreateInputConnection()
:
public class MyEditText extends TextView {
public MyEditText(Context context) {
this(context, null);
}
public MyEditText(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.editTextStyle);
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
return null;
}
@Override
protected boolean getDefaultEditable() {
return true;
}
@Override
protected MovementMethod getDefaultMovementMethod() {
return ArrowKeyMovementMethod.getInstance();
}
@Override
public Editable getText() {
return (Editable) super.getText();
}
@Override
public void setText(CharSequence text, BufferType type) {
super.setText(text, BufferType.EDITABLE);
}
/**
* Convenience for {@link Selection#setSelection(Spannable, int, int)}.
*/
public void setSelection(int start, int stop) {
Selection.setSelection(getText(), start, stop);
}
/**
* Convenience for {@link Selection#setSelection(Spannable, int)}.
*/
public void setSelection(int index) {
Selection.setSelection(getText(), index);
}
/**
* Convenience for {@link Selection#selectAll}.
*/
public void selectAll() {
Selection.selectAll(getText());
}
/**
* Convenience for {@link Selection#extendSelection}.
*/
public void extendSelection(int index) {
Selection.extendSelection(getText(), index);
}
@Override
public void setEllipsize(TextUtils.TruncateAt ellipsis) {
if (ellipsis == TextUtils.TruncateAt.MARQUEE) {
throw new IllegalArgumentException("EditText cannot use the ellipsize mode "
+ "TextUtils.TruncateAt.MARQUEE");
}
super.setEllipsize(ellipsis);
}
}
在哪里,关键是要拒绝InputConnection。这将删除意见,并删除了内存泄漏。
Where the trick is to refuse the InputConnection. This removes the suggestions and removes the memory leak.
希望这可以帮助你..
Hope this helps you to..
这篇关于EditText上导致内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!