title: Parcelable nested writeTypedList with same class
body: <p>To give an idea of what I am doing. I have a <code>Main activity</code> that allows you to add names to a <code>recyclerView</code> then start a round that sends to an <code>Arraylist</code> of people through an Intent to <code>CurrentMatchActivity</code>. after a while of user input it launches another instance of <code>CurrentMatchActivity</code> by passing an <code>Arraylist</code> of people to a new <code>CurrentMatchActivity</code>.</p>
  
  <p>Here is the <code>Person class</code> </p>
  
  <pre><code>public class Person implements Parcelable {
      private String name;
      private int wins;
      private long totalWins;
      private boolean stillPlaying;
      private ArrayList&lt;Person&gt; previousOpponents;
  
      Person(String name)
      {
          this.name = name;
          wins = 0;
          totalWins = 0;
          stillPlaying = true;
          previousOpponents = new ArrayList&lt;&gt;();
      }
  
      public void setStillPlaying(boolean playing)
      {
          stillPlaying = playing;
      }
  
      public void addOpponent(Person person) {
          previousOpponents.add(person);
      }
  
      public boolean hasFought(Person person) {
          return previousOpponents.contains(person);
      }
  
      @Override
      public int describeContents() {
          return 0;
      }
  
      private Person(Parcel in)
      {
          name = in.readString();
          wins = in.readInt();
          totalWins = in.readLong();
          stillPlaying = (boolean) in.readValue(null);
          previousOpponents = new ArrayList&lt;&gt;();
          in.readTypedList(previousOpponents, null);
      }
  
      @Override
      public void writeToParcel(Parcel dest, int flags) {
          dest.writeString(name);
          dest.writeInt(wins);
          dest.writeLong(totalWins);
          dest.writeValue(stillPlaying);
          dest.writeTypedList(previousOpponents);
      }
  
      public static final Parcelable.Creator&lt;Person&gt; CREATOR = new Parcelable.Creator&lt;Person&gt;() {
          public Person createFromParcel(Parcel in) {
              return new Person(in);
          }
  
          public Person[] newArray(int size) {
              return new Person[size];
          }
      };
  }
  </code></pre>
  
  <p>Here is the <code>CurrentMatchActivity</code> </p>
  
  <pre><code>package omarzious.myapplication;
  
  public class CurrentMatchActivity extends Activity {
  
      private ArrayList&lt;Person&gt; people;
      private RecyclerView mRecyclerView;
      private RecyclerView.Adapter mAdapter;
      private RecyclerView.LayoutManager mLayoutManager;
      private int round;
  
      private RetainedFragment dataFragment;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_current_match);
  
          FragmentManager fm = getFragmentManager();
          dataFragment = (RetainedFragment) fm.findFragmentByTag("currentMatchData");
  
          if (dataFragment == null){
              dataFragment = new RetainedFragment();
              fm.beginTransaction().add(dataFragment, "currentMatchData").commit();
              round = getIntent().getIntExtra("round",1);
              people = getIntent().getParcelableArrayListExtra("people");
              prepareMatch();
          }
          else
          {
              people = dataFragment.getData();
          }
  
          this.setTitle(getString(R.string.round)+" "+round);
          mRecyclerView = (RecyclerView) findViewById(R.id.current_match_recycler_view);
  
          mLayoutManager = new LinearLayoutManager(this);
          mRecyclerView.setLayoutManager(mLayoutManager);
  
          mAdapter = new CurrentMatchAdapter(people, getApplicationContext());
          mRecyclerView.setAdapter(mAdapter);
  
          // Swipe Portion
  
          SwipeableRecyclerViewTouchListener swipeTouchListener = new SwipeableRecyclerViewTouchListener(mRecyclerView,
                  new SwipeableRecyclerViewTouchListener.SwipeListener() {
                      private int personIndex;
                      @Override
                      public boolean canSwipe(int position)
                      {
  
                          if (position == (int)people.size()/2)
                          {
                              return false;
                          }
                          return people.get(position*2).isStillPlaying();
                      }
  
                      @Override
                      public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
                          for (int position : reverseSortedPositions)
                          {
                              personIndex = position*2;
                              //personBeat(personIndex, personIndex+1);
  
                              people.get(personIndex).won();
                              mAdapter.notifyItemChanged(position);
  
                              // if player on right won
  
                              if (people.get(personIndex).isWinner())
                              {
                                  people.get(personIndex).setStillPlaying(false);
                                  people.get(personIndex+1).setStillPlaying(false);
  
                                  if (checkForRoundEnd())
                                  {
                                      startNewRound();
                                  }
                              }
                          }
                          mAdapter.notifyDataSetChanged();
                      }
  
                      public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
                          for (int position : reverseSortedPositions) {
                              personIndex = position*2+1;
  
                              people.get(personIndex).won();
                              mAdapter.notifyItemChanged(personIndex);
  
                              // if player on left won
                              if (people.get(personIndex).isWinner())
                              {
                                  people.get(personIndex).setStillPlaying(false);
                                  people.get(personIndex-1).setStillPlaying(false);
  
                                  if (checkForRoundEnd())
                                  {
                                      startNewRound();
                                  }
                              }
                          }
                          mAdapter.notifyDataSetChanged();
                      }
                  });
  
          mRecyclerView.addOnItemTouchListener(swipeTouchListener);
      }
  
      public void checkForRematches()
      {
          int i = 0;
          Person personA;
          Person personB;
          ListIterator&lt;Person&gt; a;
  
          boolean collision = false;
          int numberOfItterations = 0;
  
         // do {
              a = people.listIterator();
              collision = false;
              i=0;
              while ( i &lt; (int)(people.size() / 2))
              {
                  personA = a.next();
                  personB = a.next();
                  i++;
  
                  if (personA.hasFought(personB)) {
                      a.remove();
                      a.add(personB);
                      people.add(personB);
                      collision = true;
                      Toast.makeText(this,"WTF", Toast.LENGTH_SHORT);
                  }
              }
              numberOfItterations++;
         // } while(collision);
  
          Toast.makeText(this, "prepare match had to itterate "+numberOfItterations+ "times", Toast.LENGTH_SHORT).show();
      }
  
      public void prepareMatch() {
          Collections.shuffle(people);
  
          int i = 0;
          Person personA;
          Person personB;
          ListIterator&lt;Person&gt; a = people.listIterator();
  
          if (round &gt; 1)
          {
          //    checkForRematches();
          }
  
          while (i &lt; (int)(people.size() / 2))
          {
              personA = a.next();
              personB = a.next();
              i++;
  
              personA.addOpponent(personB);
              personB.addOpponent(personA);
          }
      }
  
      public boolean checkForRoundEnd()
      {
          int stillPlayingAllowed = people.size() % 2;
          int peopleStillPlaying = 0;
  
          for (Person person : people) {
              if (person.isStillPlaying()) {
                  peopleStillPlaying++;
              }
          }
          return peopleStillPlaying == stillPlayingAllowed;
      }
  
      public void startNewRound()
      {
          Iterator&lt;Person&gt; i = people.iterator();
          Person person;
          while (i.hasNext()) {
              person = i.next();
              if (!person.isWinner() &amp;&amp; !person.isStillPlaying())
              {
                  i.remove();
              }
              person.clearWins();
              person.setStillPlaying(true);
          }
          if (people.size() &gt; 1) {
              Toast.makeText(this, "Starting new round", Toast.LENGTH_SHORT).show();
              Intent intent = new Intent(this, CurrentMatchActivity.class);
              intent.putExtra("round",++round);
              intent.putParcelableArrayListExtra("people", people);
              startActivity(intent);
          }
          else
          {
              Intent intent = new Intent(this, GameOverActivity.class);
              intent.putParcelableArrayListExtra("people", people);
              startActivity(intent);
          }
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.menu_current_match, menu);
          return true;
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          // Handle action bar item clicks here. The action bar will
          // automatically handle clicks on the Home/Up button, so long
          // as you specify a parent activity in AndroidManifest.xml.
          int id = item.getItemId();
  
          //noinspection SimplifiableIfStatement
          if (id == R.id.action_settings) {
              return true;
          }
  
          return super.onOptionsItemSelected(item);
      }
  
      @Override
      public void onDestroy()
      {
          super.onDestroy();
          dataFragment.setData(people);
      }
  }
  </code></pre>
  
  <p>now the odd part is it works fine. unless I activate the code.</p>
  
  <pre><code>public void prepareMatch() {
      Collections.shuffle(people);
      int i = 0;
      Person personA;
      Person personB;
      ListIterator&lt;Person&gt; a;
  
      while (i &lt; (int)(people.size() / 2))
      {
          personA = a.next();
          personB = a.next();
          i++;
  
          personA.addOpponent(personB);
          personB.addOpponent(personA);
      }
  }
  </code></pre>
  
  <p>which causes a <code>null</code> pointer crash in the <code>MainAdapter</code></p>
  
  <p>The <code>mainActivity</code> uses the <code>mainAdapter</code>. but the <code>currentMatchActivity</code> uses a CurrentMatch adapter.. And the crash happens when it tries to create an <code>CurrentMatchActivity</code> from the <code>CurrentMatchActivity</code>.</p>
  
  <p>I don't believe that <code>MainAdapter</code> should even be in use here... only <code>CurrentMatchAdapter</code>.  Furthermore... I don't see how activating the <code>prepareMatch</code> function should affect the flow of my code in that way..</p>
  
  <p>Edit: found out that it was crashing because of because of the <code>parcelable</code>.  Guess it didn't like a person list inside of a person list.</p>