From 5af6703157c02ad9c2a02e2be5b3b7bbe04dbc72 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 30 Jul 2017 18:44:57 -0500 Subject: [PATCH] binding: Weakly reference adapter in list change callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the ObservableListAdapter to be garbage collected along with its activity. On the next list change, the OnListChangedCallback will detect that the adapter is gone and clean itself up. This avoids needing to manually remove the list from the adapter, as would otherwise be required to break the reference cycle adapter→list→listener→adapter. This will be relevant once the list of profiles outlives the activity. Signed-off-by: Jason A. Donenfeld --- .../android/ObservableListAdapter.java | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/wireguard/android/ObservableListAdapter.java b/app/src/main/java/com/wireguard/android/ObservableListAdapter.java index 3b1cf5f..475bafb 100644 --- a/app/src/main/java/com/wireguard/android/ObservableListAdapter.java +++ b/app/src/main/java/com/wireguard/android/ObservableListAdapter.java @@ -10,6 +10,8 @@ import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListAdapter; +import java.lang.ref.WeakReference; + /** * A generic ListAdapter backed by an ObservableList. */ @@ -18,7 +20,7 @@ class ObservableListAdapter extends BaseAdapter implements ListAdapter { private final int layoutId; private final LayoutInflater layoutInflater; private ObservableList list; - private final OnListChangedCallback> callback = new OnListChangedCallback<>(); + private final OnListChangedCallback callback = new OnListChangedCallback<>(this); ObservableListAdapter(Context context, int layoutId, ObservableList list) { this.layoutInflater = LayoutInflater.from(context); @@ -60,32 +62,44 @@ class ObservableListAdapter extends BaseAdapter implements ListAdapter { } } - private class OnListChangedCallback> - extends ObservableList.OnListChangedCallback { + private static class OnListChangedCallback + extends ObservableList.OnListChangedCallback> { + + private final WeakReference> weakAdapter; + + private OnListChangedCallback(ObservableListAdapter adapter) { + weakAdapter = new WeakReference<>(adapter); + } + @Override - public void onChanged(L sender) { - ObservableListAdapter.this.notifyDataSetChanged(); + public void onChanged(ObservableList sender) { + final ObservableListAdapter adapter = weakAdapter.get(); + if (adapter != null) + adapter.notifyDataSetChanged(); + else + sender.removeOnListChangedCallback(this); } @Override - public void onItemRangeChanged(L sender, int positionStart, int itemCount) { - ObservableListAdapter.this.notifyDataSetChanged(); + public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) { + onChanged(sender); } @Override - public void onItemRangeInserted(L sender, int positionStart, int itemCount) { - ObservableListAdapter.this.notifyDataSetChanged(); + public void onItemRangeInserted(ObservableList sender, int positionStart, + int itemCount) { + onChanged(sender); } @Override - public void onItemRangeMoved(L sender, int fromPosition, int toPosition, + public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) { - ObservableListAdapter.this.notifyDataSetChanged(); + onChanged(sender); } @Override - public void onItemRangeRemoved(L sender, int positionStart, int itemCount) { - ObservableListAdapter.this.notifyDataSetChanged(); + public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) { + onChanged(sender); } } }