summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSamuel Holland <samuel@sholland.org>2017-07-30 18:44:57 -0500
committerSamuel Holland <samuel@sholland.org>2017-07-30 18:44:57 -0500
commite000a17bc95852eb599c250806faf25e8c9b1e70 (patch)
treec2513661dd83ecfd3a7080a7abad3800cd48cea6
parent187c2d977735456d56a8db74413fac6ef50c9161 (diff)
binding: Weakly reference adapter in list change callback
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.
-rw-r--r--app/src/main/java/com/wireguard/android/ObservableListAdapter.java40
1 files 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 3b1cf5f8..475bafbf 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<T> extends BaseAdapter implements ListAdapter {
private final int layoutId;
private final LayoutInflater layoutInflater;
private ObservableList<T> list;
- private final OnListChangedCallback<ObservableList<T>> callback = new OnListChangedCallback<>();
+ private final OnListChangedCallback<T> callback = new OnListChangedCallback<>(this);
ObservableListAdapter(Context context, int layoutId, ObservableList<T> list) {
this.layoutInflater = LayoutInflater.from(context);
@@ -60,32 +62,44 @@ class ObservableListAdapter<T> extends BaseAdapter implements ListAdapter {
}
}
- private class OnListChangedCallback<L extends ObservableList<T>>
- extends ObservableList.OnListChangedCallback<L> {
+ private static class OnListChangedCallback<U>
+ extends ObservableList.OnListChangedCallback<ObservableList<U>> {
+
+ private final WeakReference<ObservableListAdapter<U>> weakAdapter;
+
+ private OnListChangedCallback(ObservableListAdapter<U> adapter) {
+ weakAdapter = new WeakReference<>(adapter);
+ }
+
@Override
- public void onChanged(L sender) {
- ObservableListAdapter.this.notifyDataSetChanged();
+ public void onChanged(ObservableList<U> sender) {
+ final ObservableListAdapter<U> 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<U> sender, int positionStart, int itemCount) {
+ onChanged(sender);
}
@Override
- public void onItemRangeInserted(L sender, int positionStart, int itemCount) {
- ObservableListAdapter.this.notifyDataSetChanged();
+ public void onItemRangeInserted(ObservableList<U> sender, int positionStart,
+ int itemCount) {
+ onChanged(sender);
}
@Override
- public void onItemRangeMoved(L sender, int fromPosition, int toPosition,
+ public void onItemRangeMoved(ObservableList<U> 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<U> sender, int positionStart, int itemCount) {
+ onChanged(sender);
}
}
}