Android/Java:TextInputEditText 在其 Fragment 被销毁时泄漏
Android/Java: TextInputEditText leaks when it's Fragment gets destroyed
我有一个布局简单的 Fragment
:
ConstraintLayout
-> LinearLayout
-> TextInputLayout
-> TextInputEditText
它看起来不错并且可以工作,但是当我导航到另一个 Fragment
时,当前的 destroyed、LeakCanary 向我显示与 TextInputEditText
相关的意外 内存泄漏 ,即使我在 onDestroyView()
.[=24= 中将其设置为 null
]
LeakCanary 报告:
ConstraintLayout leaked
-> InputMethodManager$ControlledInputConnectionWrapper.mInputConnection
-> EditableInputConnection.mTextView
-> TextInputEditText.mParent
MyFragment.java
public class MyFragment extends Fragment {
private View view;
private EditText et;
public MyFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.my_layout, container, false);
et = view.findViewById(R.id.my_et);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
et = null;
view = null;
// No difference, if I call super.onDestroyView(); here
}
}
my_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/my_cl"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.design.widget.TextInputEditText
android:id="@+id/my_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="numberPassword" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
有什么想法吗?提前致谢!
编辑 1
当我从布局中删除 android.support.design.widget.TextInputEditText
时,泄漏不会出现。
这不是解决方案,但可能会引导您找到解决方案。
由于您使用的是 LeakCanary,请检查其 AndroidExcludedRefs.java 文件,其中包含 Android SDK 本身或某些制造商版本中的已知泄漏列表。
它包含几个已知的 InputMethodManager 泄漏,其中之一可能是您所看到的泄漏的原因。两者都包含 "Hack" 可能解决方法的链接。
INPUT_METHOD_MANAGER__SERVED_VIEW(SDK_INT >= ICE_CREAM_SANDWICH_MR1 && SDK_INT <= N_MR1) {
@Override void add(ExcludedRefs.Builder excluded) {
String reason = "When we detach a view that receives keyboard input, the InputMethodManager"
+ " leaks a reference to it until a new view asks for keyboard input."
+ " Tracked here: https://code.google.com/p/android/issues/detail?id=171190"
+ " Hack: https://gist.github.com/pyricau/4df64341cc978a7de414";
excluded.instanceField("android.view.inputmethod.InputMethodManager", "mNextServedView")
.reason(reason);
excluded.instanceField("android.view.inputmethod.InputMethodManager", "mServedView")
.reason(reason);
excluded.instanceField("android.view.inputmethod.InputMethodManager",
"mServedInputConnection").reason(reason);
}
},
INPUT_METHOD_MANAGER__ROOT_VIEW(SDK_INT >= ICE_CREAM_SANDWICH_MR1 && SDK_INT <= M) {
@Override void add(ExcludedRefs.Builder excluded) {
excluded.instanceField("android.view.inputmethod.InputMethodManager", "mCurRootView")
.reason("The singleton InputMethodManager is holding a reference to mCurRootView long"
+ " after the activity has been destroyed."
+ " Observed on ICS MR1: https://github.com/square/leakcanary/issues/1"
+ "#issuecomment-100579429"
+ " Hack: https://gist.github.com/pyricau/4df64341cc978a7de414");
}
},
我有一个布局简单的 Fragment
:
ConstraintLayout
-> LinearLayout
-> TextInputLayout
-> TextInputEditText
它看起来不错并且可以工作,但是当我导航到另一个 Fragment
时,当前的 destroyed、LeakCanary 向我显示与 TextInputEditText
相关的意外 内存泄漏 ,即使我在 onDestroyView()
.[=24= 中将其设置为 null
]
LeakCanary 报告:
ConstraintLayout leaked
-> InputMethodManager$ControlledInputConnectionWrapper.mInputConnection
-> EditableInputConnection.mTextView
-> TextInputEditText.mParent
MyFragment.java
public class MyFragment extends Fragment {
private View view;
private EditText et;
public MyFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.my_layout, container, false);
et = view.findViewById(R.id.my_et);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
et = null;
view = null;
// No difference, if I call super.onDestroyView(); here
}
}
my_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/my_cl"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.design.widget.TextInputEditText
android:id="@+id/my_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="numberPassword" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
有什么想法吗?提前致谢!
编辑 1
当我从布局中删除 android.support.design.widget.TextInputEditText
时,泄漏不会出现。
这不是解决方案,但可能会引导您找到解决方案。
由于您使用的是 LeakCanary,请检查其 AndroidExcludedRefs.java 文件,其中包含 Android SDK 本身或某些制造商版本中的已知泄漏列表。
它包含几个已知的 InputMethodManager 泄漏,其中之一可能是您所看到的泄漏的原因。两者都包含 "Hack" 可能解决方法的链接。
INPUT_METHOD_MANAGER__SERVED_VIEW(SDK_INT >= ICE_CREAM_SANDWICH_MR1 && SDK_INT <= N_MR1) {
@Override void add(ExcludedRefs.Builder excluded) {
String reason = "When we detach a view that receives keyboard input, the InputMethodManager"
+ " leaks a reference to it until a new view asks for keyboard input."
+ " Tracked here: https://code.google.com/p/android/issues/detail?id=171190"
+ " Hack: https://gist.github.com/pyricau/4df64341cc978a7de414";
excluded.instanceField("android.view.inputmethod.InputMethodManager", "mNextServedView")
.reason(reason);
excluded.instanceField("android.view.inputmethod.InputMethodManager", "mServedView")
.reason(reason);
excluded.instanceField("android.view.inputmethod.InputMethodManager",
"mServedInputConnection").reason(reason);
}
},
INPUT_METHOD_MANAGER__ROOT_VIEW(SDK_INT >= ICE_CREAM_SANDWICH_MR1 && SDK_INT <= M) {
@Override void add(ExcludedRefs.Builder excluded) {
excluded.instanceField("android.view.inputmethod.InputMethodManager", "mCurRootView")
.reason("The singleton InputMethodManager is holding a reference to mCurRootView long"
+ " after the activity has been destroyed."
+ " Observed on ICS MR1: https://github.com/square/leakcanary/issues/1"
+ "#issuecomment-100579429"
+ " Hack: https://gist.github.com/pyricau/4df64341cc978a7de414");
}
},