Fixing memory leak in QSB widget
> Instead of recreating the whole fragment, only recreating the views
when reinflating
> Binding the fragment in xml instead of in code
This prevents duplicate fragment binding
Bug: 29120662
Change-Id: I25b942f64d68f25e1358f15d8a919daeebdcff9c
diff --git a/res/layout/qsb_container.xml b/res/layout/qsb_container.xml
index 3de2876..55c7390 100644
--- a/res/layout/qsb_container.xml
+++ b/res/layout/qsb_container.xml
@@ -20,4 +20,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/qsb_container"
- android:padding="0dp" />
\ No newline at end of file
+ android:padding="0dp" >
+
+ <fragment
+ android:name="com.android.launcher3.QsbContainerView$QsbFragment"
+ android:layout_width="match_parent"
+ android:tag="qsb_view"
+ android:layout_height="match_parent"/>
+</com.android.launcher3.QsbContainerView>
\ No newline at end of file
diff --git a/src/com/android/launcher3/QsbContainerView.java b/src/com/android/launcher3/QsbContainerView.java
index 0a112d2..f931aba 100644
--- a/src/com/android/launcher3/QsbContainerView.java
+++ b/src/com/android/launcher3/QsbContainerView.java
@@ -18,7 +18,6 @@
import android.app.Activity;
import android.app.Fragment;
-import android.app.FragmentManager;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -44,8 +43,6 @@
*/
public class QsbContainerView extends FrameLayout {
- private boolean mBound;
-
public QsbContainerView(Context context) {
super(context);
}
@@ -59,17 +56,6 @@
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- if (!mBound) {
- FragmentManager fm = ((Launcher) getContext()).getFragmentManager();
- fm.beginTransaction().add(R.id.qsb_container, new QsbFragment()).commit();
- mBound = true;
- }
- }
-
- @Override
public void setPadding(int left, int top, int right, int bottom) {
super.setPadding(0, 0, 0, 0);
}
@@ -103,6 +89,8 @@
getContext().registerReceiver(mRebindReceiver, filter);
}
+ private FrameLayout mWrapper;
+
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -110,7 +98,12 @@
if (savedInstanceState != null) {
sSavedWidgetId = savedInstanceState.getInt(QSB_WIDGET_ID, -1);
}
+ mWrapper = new FrameLayout(getContext());
+ mWrapper.addView(createQsb(inflater, mWrapper));
+ return mWrapper;
+ }
+ private View createQsb(LayoutInflater inflater, ViewGroup container) {
Launcher launcher = (Launcher) getActivity();
mWidgetInfo = getSearchWidgetProvider(launcher);
if (mWidgetInfo == null) {
@@ -222,10 +215,9 @@
}
private void rebindFragment() {
- if (getActivity() != null) {
- // Recreate the fragment. This will cause the qsb to be inflated again.
- getActivity().getFragmentManager().beginTransaction()
- .replace(R.id.qsb_container, new QsbFragment()).commit();
+ if (mWrapper != null && getActivity() != null) {
+ mWrapper.removeAllViews();
+ mWrapper.addView(createQsb(getActivity().getLayoutInflater(), mWrapper));
}
}