How to handle checkboxes inside CustomArrayAdapter
<p>I am trying to handle 'check/uncheck' of a set of checkboxes inside a CustomArrayAdapter.</p>

<p>The requirement is that when I 'check' a checkbox, the other check boxes should remain checked/unchecked based on a specific condition.</p>

<p>The approach I am planning is that I will be storing all the 'Checkbox' objects in an ArrayList and adding them to my SharedPreferences file using 'gson'. When I 'check' a checkbox I will retrieve each one of them and change the state of the checkboxes based on my criteria.</p>

<p>For some reason storing a 'Checkbox' object in SharedPreferences sends the compiler into an infinite loop and I get the following stack log:</p>

<pre><code>09-05 07:52:20.186 1560-1600/millennia.sniffbt I/OpenGLRenderer: Initialized EGL, version 1.4
09-05 07:52:20.187 1560-1600/millennia.sniffbt D/OpenGLRenderer: Swap behavior 1
09-05 07:52:44.803 1560-1565/millennia.sniffbt I/art: Do partial code cache collection, code=124KB, data=100KB
09-05 07:52:44.804 1560-1565/millennia.sniffbt I/art: After code cache collection, code=124KB, data=100KB
09-05 07:52:44.804 1560-1565/millennia.sniffbt I/art: Increasing code cache capacity to 512KB
09-05 07:52:46.339 1560-1567/millennia.sniffbt W/art: Suspending all threads took: 16.280ms
09-05 07:52:48.700 1560-1571/millennia.sniffbt I/art: Background partial concurrent mark sweep GC freed 284903(5MB) AllocSpace objects, 20(1932KB) LOS objects, 37% free, 26MB/42MB, paused 4.525ms total 115.535ms
09-05 07:52:49.627 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 517140(8MB) AllocSpace objects, 31(3MB) LOS objects, 25% free, 31MB/42MB, paused 5.249ms total 97.072ms
09-05 07:52:49.976 1560-1567/millennia.sniffbt W/art: Suspending all threads took: 15.674ms
09-05 07:52:50.410 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 368915(6MB) AllocSpace objects, 20(2MB) LOS objects, 16% free, 35MB/42MB, paused 5.346ms total 90.929ms
09-05 07:52:50.804 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 293352(5MB) AllocSpace objects, 17(2MB) LOS objects, 13% free, 36MB/42MB, paused 5.083ms total 93.860ms
09-05 07:52:51.226 1560-1571/millennia.sniffbt I/art: Background partial concurrent mark sweep GC freed 333422(5MB) AllocSpace objects, 19(2MB) LOS objects, 29% free, 37MB/53MB, paused 6.722ms total 178.796ms
09-05 07:52:51.813 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 602192(10MB) AllocSpace objects, 30(3MB) LOS objects, 23% free, 40MB/53MB, paused 6.137ms total 117.126ms
09-05 07:52:52.374 1560-1571/millennia.sniffbt I/art: Background sticky concurrent mark sweep GC freed 506509(8MB) AllocSpace objects, 24(3MB) LOS objects, 19% free, 42MB/53MB, paused 6.292ms total 112.676ms
09-05 07:52:52.605 1560-1567/millennia.sniffbt W/art: Debugger attempted to resume all threads without having suspended them all before.
09-05 07:52:52.615 1560-1567/millennia.sniffbt I/art: Debugger is no longer active
</code></pre>

<p>Here is my CustomArrayAdapter</p>

<p>CustomArrayAdapter.java:</p>

<pre><code>public class CustomArrayAdapter extends ArrayAdapter&lt;Row&gt; {
    Row[] rowItems = null;
    Context context;
    SharedPreferences appPrefs;

public CustomArrayAdapter(MyInterface fragmentActivity, Context context, Row[] resource) {
    super(context, R.layout.row_with_cb, resource);
    this.rowItems = resource;
    this.context = context;
    cf = new CommonFunctions();
    appPrefs = getContext().getSharedPreferences(getContext().getString(R.string.app_shared_pref_filename), Context.MODE_PRIVATE);
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = ((Activity)this.context).getLayoutInflater();
    convertView = inflater.inflate(R.layout.row_with_cb, parent, false);
    TextView name = (TextView)convertView.findViewById(R.id.row_with_cb_Txt);
    CheckBox cb = (CheckBox)convertView.findViewById(R.id.row_with_cb_ChkBox);

    // Add Checkboxes into ArrayList and store em away
    ArrayList&lt;CheckBox&gt; arrCheckBoxes = new ArrayList&lt;&gt;();
    arrCheckBoxes.add(cb);

    SharedPreferences.Editor prefEditor = appPrefs.edit();
    Gson gson = new Gson();
    String json;
    Type typeOfObject = new TypeToken&lt;ArrayList&lt;CheckBox&gt;&gt;(){}.getType();
    json = gson.toJson(arrCheckBoxes, typeOfObject); // MY COMPILER GOES INTO INFINITE LOOP HERE
    prefEditor.putString("ListOfChkBoxes", json);
    prefEditor.apply();

    // Create a onClickListener when a checkbox is selected
    cb.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            CheckBox cb = (CheckBox) v;
            rowItems[position].setCB(cb.isChecked());
        }
    });

    return convertView;
}
</code></pre>

<p>I have 2 questions:</p>

<ol>
<li>Why does storing a 'Checkbox' send the compiler into infinite loop?</li>
<li>Is there a better way to store and retrieve the checkboxes?</li>
</ol>