From b5a869f177e78980c86a3371a5ded3fa988d563e Mon Sep 17 00:00:00 2001 From: pegasko Date: Sun, 23 Jun 2024 17:27:40 +0300 Subject: [PATCH] ConcurrentModification bugfix & NOTICE udpate --- NOTICE | 5 +- .../ui/activity/EventEditTagsAdapter.java | 67 ++++++++++--------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/NOTICE b/NOTICE index dd879f5..904b675 100644 --- a/NOTICE +++ b/NOTICE @@ -1,3 +1,4 @@ -1. This source code is prohibited from usage of any kind in any kind of AI-based (neural networks, graph networks, prediction models, weighted predictors and/or any machine learning algorhitms of any kind) software and/or models (including, but not limited to using as training data; using to build search index; used as token sequence for vectorization; used as input of any AI-based software and/or models); +1. This source code is prohibited from usage of any kind in any kind of AI/NN/ML-based (neural networks, graph networks, prediction models, weighted predictors and/or any machine learning algorhitms of any kind) software and/or models (including, but not limited to using as training data; using to build search index; used as token sequence for vectorization; used as input of any AI/NN/ML-based software and/or models); 2. Initial creator attribution (pegasko) must persist among all subsequent copies of any depth on any media; -3. Take care of your cat(s); +3. Сommercial (or any kind of profit) distribution is allowed only with explicit agreement of the author (pegasko); +4. Take care of your cat(s); diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventEditTagsAdapter.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventEditTagsAdapter.java index a2975a6..fa1b493 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventEditTagsAdapter.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventEditTagsAdapter.java @@ -26,26 +26,21 @@ import android.widget.Filter; import android.widget.TextView; import java.util.ArrayList; -import java.util.List; import art.pegasko.yeeemp.base.TagStat; public class EventEditTagsAdapter extends ArrayAdapter { public static final String TAG = EventEditTagsAdapter.class.getSimpleName(); - private ArrayList items; - private ArrayList itemsAll; - private ArrayList suggestions; - private int viewResourceId; - private int viewFieldId; + private ArrayList tags; private LayoutInflater inflater; + private final int viewResourceId; + private final int viewFieldId; @SuppressWarnings("unchecked") - public EventEditTagsAdapter(Context context, int viewResourceId, int viewFieldId, ArrayList items) { - super(context, viewResourceId, items); - this.items = items; - this.itemsAll = (ArrayList) items.clone(); - this.suggestions = new ArrayList(); + public EventEditTagsAdapter(Context context, int viewResourceId, int viewFieldId, ArrayList tags) { + super(context, viewResourceId, tags); + this.tags = tags; this.viewResourceId = viewResourceId; this.viewFieldId = viewFieldId; this.inflater = LayoutInflater.from(context); @@ -71,7 +66,7 @@ public class EventEditTagsAdapter extends ArrayAdapter { throw new RuntimeException("You must supply a resource ID for a TextView"); } - text.setText(items.get(position).tag.getName() + " (" + Integer.toString(items.get(position).count) + ")"); + text.setText(tags.get(position).tag.getName() + " (" + tags.get(position).count + ")"); return convertView; } @@ -81,7 +76,11 @@ public class EventEditTagsAdapter extends ArrayAdapter { return nameFilter; } - Filter nameFilter = new Filter() { + private Filter nameFilter = new Filter() { + // TODO: Stop using mutable global + // Reusable filter result + private ArrayList tagsSuggestions = new ArrayList(); + public String convertResultToString(Object resultValue) { String str = ((TagStat) (resultValue)).tag.getName(); return str; @@ -89,31 +88,39 @@ public class EventEditTagsAdapter extends ArrayAdapter { @Override protected FilterResults performFiltering(CharSequence constraint) { - if (constraint != null) { - suggestions.clear(); - for (TagStat product : itemsAll) { - if (product.tag.getName().contains(constraint.toString().toLowerCase())) { - suggestions.add(product); + synchronized (tagsSuggestions) { + if (constraint != null) { + tagsSuggestions.clear(); + for (TagStat tag : tags) { + if (tag.tag.getName().contains(constraint.toString().toLowerCase())) { + tagsSuggestions.add(tag); + } } + FilterResults filterResults = new FilterResults(); + // TODO: Spank me for using global mutable instance for returning immutable result (causes concurrent modification when publishResults()) + filterResults.values = tagsSuggestions; + filterResults.count = tagsSuggestions.size(); + return filterResults; + } else { + return new FilterResults(); } - FilterResults filterResults = new FilterResults(); - filterResults.values = suggestions; - filterResults.count = suggestions.size(); - return filterResults; - } else { - return new FilterResults(); } } @Override protected void publishResults(CharSequence constraint, FilterResults results) { - @SuppressWarnings("unchecked") ArrayList filteredList = (ArrayList) results.values; - if (results != null && results.count > 0) { - clear(); - for (TagStat c : filteredList) { - add(c); + if (results.values == null) + return; + + synchronized (results.values) { + ArrayList filteredList = (ArrayList) results.values; + if (results.count > 0) { + clear(); + for (TagStat c : filteredList) { + add(c); + } + notifyDataSetChanged(); } - notifyDataSetChanged(); } } };