title: Android: Changes to custom object deleted after orientation change
body: <p>I have a class that displays some data values that belongs to a custom object passed through an intent from the main class. When I change the orientation everything changes fine since it just goes back to the intent for the class. </p>
  
  <p>However, the user is able to edit the object and return to the class with the changes visible. When you change the orientation after having edited the object, it reverts back to the original intent. </p>
  
  <p>I've tried creating an onSaveInstanceState as well as an onRestoreInstanceState to prevent the calling of the first intent, but it's not working well.</p>
  
  <p>Here is the code for the class I'm having issues with:</p>
  
  <pre><code>import android.app.Activity;
  import android.content.Intent;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.view.View;
  import android.widget.Button;
  import android.widget.TextView;
  
  import java.util.Arrays;
  import java.util.List;
  
  public class RecipeTextView extends AppCompatActivity {
  
      private TextView mRecipeName;
      private TextView mServings;
      private TextView mCookTime;
      private TextView mPrepTime;
      private TextView mDirections;
      private TextView mIngredients;
      private Button mEditButton;
      private int REQUEST_CODE = 1;
      Recipe selectedRecipe = new Recipe();
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          //selectedRecipe = savedInstanceState.getParcelable("savedRecipes");
          selectedRecipe = getIntent().getExtras().getParcelable("view_recipe_key");
          loadActivity(selectedRecipe);
      }
  
      @Override
      protected void onSaveInstanceState(Bundle savedInstanceState){
          super.onSaveInstanceState(savedInstanceState);
          savedInstanceState.putParcelable("savedRecipes", selectedRecipe);
      }
  
      @Override
      protected void onRestoreInstanceState(Bundle savedInstanceState) {
          super.onRestoreInstanceState(savedInstanceState);
          Recipe restoreRecipe = savedInstanceState.getParcelable("savedRecipes");
          loadActivity(restoreRecipe);
      }
  
  
      protected void loadActivity(final Recipe selectedRecipe){
          setContentView(R.layout.activity_recipe_text_view);
  
          mRecipeName = (TextView) findViewById(R.id.recipe_name_text_view);
          mRecipeName.setText(selectedRecipe.getRecipeName());
  
          mServings = (TextView) findViewById(R.id.serving_text_view);
          if(selectedRecipe.getServings() != null &amp;&amp; selectedRecipe.getServings() != "") {
              mServings.setText(selectedRecipe.getServings());
          }
  
          mPrepTime = (TextView) findViewById(R.id.prep_time_text_view);
          if(selectedRecipe.getPrepTime() != null &amp;&amp; selectedRecipe.getPrepTime() != "") {
              mPrepTime.setText("Prep time: " + selectedRecipe.getPrepTime() + " minutes");
          }
  
          mCookTime = (TextView) findViewById(R.id.cook_time_text_view);
          if(selectedRecipe.getCookTime() != null &amp;&amp; selectedRecipe.getCookTime() != "") {
              mCookTime.setText("Cook time: " + selectedRecipe.getCookTime() + " minutes");
          }
  
          //Below code builds a string concatenating a bullet to each line followed by a new line
          //Each line is an index of the directions arraylist
          List&lt;String&gt; ingredientsList = selectedRecipe.getIngredients();
          int ingredientsSize = ingredientsList.size();
          String ingredientsConcat = "";
  
          for(int i = 0; i &lt; ingredientsSize; i++){
              ingredientsConcat += "\u2022 " + ingredientsList.get(i) + "\n";
          }
          mIngredients = (TextView) findViewById(R.id.ingredients_text_view);
          if(ingredientsConcat.equals("\u2022 " + "\n") == false) {
              mIngredients.setText(ingredientsConcat);
          }
  
  
          //This code does almost the same as above for the directions, except it appends a number
          //to each line instead of a bullet.
          List&lt;String&gt; directionsList = selectedRecipe.getDirections();
          int directionsSize = directionsList.size();
          String directionsConcat = "";
  
          for(int i = 0; i &lt; directionsSize; i++){
              directionsConcat += (i + 1) + ". " + directionsList.get(i) + "\n";
          }
          mDirections = (TextView) findViewById(R.id.directions_text_view);
          if(directionsConcat.equals("1. \n") == false) {
              mDirections.setText(directionsConcat);
          }
  
          mEditButton = (Button) findViewById(R.id.edit_recipe_button);
          mEditButton.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  Intent i = new Intent(RecipeTextView.this, EditRecipe.class);
                  i.putExtra("passed_recipe_key", selectedRecipe);
                  startActivityForResult(i, REQUEST_CODE);
              }
          });
      }
  
      @Override
      //This is called when the user is finished EDITING the recipe chosen.
      protected void onActivityResult(int requestCode, int resultCode, Intent data){
          super.onActivityResult(requestCode, resultCode, data);
          if (requestCode == REQUEST_CODE){
              if(resultCode == Activity.RESULT_OK) {
                  Recipe editedRecipe = (Recipe) data.getExtras().getParcelable("recipe_key");
  
                  //Since the user is returned to this class and not RecipeList, we want to make sure that the appropriate
                  //list inside the list of recipes. This is only necessary here since creating a new recipe returns the user to the recipe list.
                  RecipeList classObject = new RecipeList();
                  classObject.updateList(editedRecipe);
                  this.loadActivity(editedRecipe);
  
              }
          }
      }
  
  
  
  }
  </code></pre>
  
  <p>The following is the code for the edit class:</p>
  
  <pre><code>import android.app.Activity;
  import android.content.Intent;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.text.Editable;
  import android.text.Selection;
  import android.text.TextUtils;
  import android.text.TextWatcher;
  import android.util.Log;
  import android.view.View;
  import android.widget.Button;
  import android.widget.EditText;
  import android.widget.TextView;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  
  //This class is used to edit a recipe. Editing includes both creating a new recipe and editing an existing one
  //The edit and create button are in RecipeTextView (Edit) and RecipeList (Create)
  //TODO: Change passes to Parcelable
  public class EditRecipe extends AppCompatActivity {
      private final String TAG = "myApp";
      private EditText mRecipeName;
      private EditText mServings;
      private EditText mPrepTime;
      private EditText mIngredients;
      private EditText mDirections;
      private Button mSaveButton;
      private EditText mCookTime;
      private int REQUEST_CODE = 1;
  
      //These are declared here so that I can use them within each edit text listener, and then set them to the values
      //of the recipe object when the save button is pushed.
  
      private String recipeName;
      private String prepTime;
      private String cookTime;
      private String servings;
      //For directions and ingredients, we will seperate these into a list of strings by \n (new line).
      private String directions;
      private String ingredients;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          Log.d(TAG, "onCreate() called");
          setContentView(R.layout.activity_edit_recipe);
  
          final Recipe passedRecipe = (Recipe) getIntent().getExtras().getParcelable("passed_recipe_key");
  
          mRecipeName = (EditText) findViewById(R.id.recipe_name_text_edit);
          mPrepTime = (EditText) findViewById(R.id.prep_time_edit_text);
          mCookTime = (EditText) findViewById(R.id.cook_time_edit_text);
          mServings = (EditText) findViewById(R.id.serving_edit_text);
          mIngredients = (EditText) findViewById(R.id.ingredients_edit_text);
          mDirections = (EditText) findViewById(R.id.directions_edit_text);
          mSaveButton = (Button) findViewById(R.id.save_edit_recipe_button);
  
  
          //The following if statements will only be triggered if this class is accessed from editing an
          //already existing recipe. Otherwise a new recipe is created.
          if(passedRecipe.getRecipeName() != null){
              mRecipeName.setText(passedRecipe.getRecipeName(), TextView.BufferType.EDITABLE);
              recipeName = passedRecipe.getRecipeName();
          }
          if(passedRecipe.getPrepTime() != null){
              mPrepTime.setText(passedRecipe.getPrepTime(), TextView.BufferType.EDITABLE);
              prepTime = passedRecipe.getPrepTime();
          }
          if(passedRecipe.getCookTime() != null){
              mCookTime.setText(passedRecipe.getCookTime(), TextView.BufferType.EDITABLE);
              cookTime = passedRecipe.getCookTime();
          }
          if(passedRecipe.getServings() != null){
              mServings.setText(passedRecipe.getServings(), TextView.BufferType.EDITABLE);
              servings = passedRecipe.getServings();
          }
          //For the array list values, we check if the array list is empty
          //If it isn't empty, we save each value of the array list into a string concatenated with a new line
          //We then set that string as the new line
          if(passedRecipe.getIngredients() != null){
              String passedIngredientString = "";
              for(int i = 0; i &lt; passedRecipe.getIngredients().size(); i++){
                  passedIngredientString += passedRecipe.getIngredients().get(i) + "\n";
              }
              mIngredients.setText(passedIngredientString, TextView.BufferType.EDITABLE);
              ingredients = passedIngredientString;
          }
          if(passedRecipe.getDirections() != null){
              String passedDirectionString = "";
              for(int i = 0; i &lt; passedRecipe.getDirections().size(); i++){
                  passedDirectionString += passedRecipe.getDirections().get(i) + "\n";
              }
              mDirections.setText(passedDirectionString, TextView.BufferType.EDITABLE);
              directions = passedDirectionString;
          }
  
  
  
          //In the following Listeners I use .trim at the end to get rid of white space users tend to leave
          //For the integer values I first store the data in a string then parse it to an int.
          mRecipeName.addTextChangedListener(new TextWatcher() {
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  
              }
  
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  recipeName = mRecipeName.getText().toString().trim();
  
              }
  
              @Override
              public void afterTextChanged(Editable s) {
  
              }
          });
  
          mPrepTime.addTextChangedListener(new TextWatcher() {
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  
              }
  
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  prepTime = mPrepTime.getText().toString().trim();
              }
  
              @Override
              public void afterTextChanged(Editable s) {
  
              }
          });
  
          mServings.addTextChangedListener(new TextWatcher() {
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  
              }
  
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  servings = mServings.getText().toString().trim();
              }
  
              @Override
              public void afterTextChanged(Editable s) {
  
              }
          });
  
          mCookTime.addTextChangedListener(new TextWatcher() {
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  
              }
  
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  cookTime = mCookTime.getText().toString().trim();
              }
  
              @Override
              public void afterTextChanged(Editable s) {
  
              }
          });
  
          mDirections.addTextChangedListener(new TextWatcher() {
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  
              }
  
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  //For now we will save this in a string, then seperate each line into an array list.
                  directions = mDirections.getText().toString().trim();
  
  
              }
  
              @Override
              public void afterTextChanged(Editable s) {
  
              }
          });
  
          mIngredients.addTextChangedListener(new TextWatcher() {
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  
              }
  
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  //For now we will save this in a string, then seperate each line into an array list.
                  ingredients = mIngredients.getText().toString().trim();
              }
  
              @Override
              public void afterTextChanged(Editable s) {
  
              }
          });
  
  
          //TODO
          mSaveButton.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  //If statement to make sure the recipe name exists. Every other value can be empty
                  //if the user wishes
                  if (TextUtils.isEmpty(recipeName)){
                      mRecipeName.setError("Recipe name can not be empty.");
                      return;
                  }
  
                  if (recipeName != null) {
                      passedRecipe.setRecipeName(recipeName);
                  }
                  if(cookTime != null) {
                      passedRecipe.setCookTime(cookTime);
                  }
                  if(prepTime != null) {
                      passedRecipe.setPrepTime(prepTime);
                  }
                  if (servings != null) {
                      passedRecipe.setServingSize(servings);
                  }
  
  
                  List&lt;String&gt; directionsList = new ArrayList&lt;String&gt;();
                  List&lt;String&gt; ingredientsList = new ArrayList&lt;String&gt;();
  
                  //Check if the edit text strings are null. if they are, add an empty string to each list
                  //If they aren't null, check if they are multi lined.
                  //If multi lined, save into a list split by new line. Otherwise, it is just one string. Add it to the list
                  if (directions != null){
                      if(directions.contains("\n")) {
                          directionsList = Arrays.asList(directions.split("\n"));
                      }
                      else{
                          directionsList = Arrays.asList(directions);
                      }
                  }
                  else{
                      directionsList.add("");
                  }
  
                  if (ingredients != null){
                      if(ingredients.contains("\n")) {
                          ingredientsList = Arrays.asList(ingredients.split("\n"));
                      }
                      else{
                          ingredientsList = Arrays.asList(ingredients);
                      }
                  }
                  else{
                      ingredientsList.add("");
                  }
  
  
                  passedRecipe.setDirections(directionsList);
                  passedRecipe.setIngredients(ingredientsList);
  
                  Intent returnIntent = new Intent(EditRecipe.this, RecipeList.class);
                  returnIntent.putExtra("recipe_key", passedRecipe);
                  setResult(Activity.RESULT_OK, returnIntent);
                  finish();
              }
          });
      }
  
  
  }
  </code></pre>
  
  <p>And just in case it's relevant the code for the main class: </p>
  
  <pre><code>import android.app.Activity;
  import android.content.Intent;
  import android.os.Parcelable;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.support.v7.widget.LinearLayoutManager;
  import android.support.v7.widget.RecyclerView;
  import android.view.View;
  import android.widget.Button;
  import java.util.ArrayList;
  
  public class RecipeList extends AppCompatActivity{
      private RecyclerView mRecyclerView;
      private RecyclerView.Adapter mAdapter;
      private RecyclerView.LayoutManager mLayoutManager;
      private int REQUEST_CODE=1;
      ArrayList&lt;Recipe&gt; recipes = new ArrayList&lt;&gt;();
  
      //TODO: Create a new taskbar
      //TODO: Test the new onSaveInstanceState
      //TODO: Create a navigaton bar.
      //BUG: When pressing backbutton on textView after editing the data is deleted and it goes back to the list.
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          if(savedInstanceState != null){
              recipes = savedInstanceState.getParcelableArrayList("savedRecipes");
          }
  
          setContentView(R.layout.activity_recipe_list);
          mRecyclerView = (RecyclerView) findViewById(R.id.list_recycler_view);
  
  
          mLayoutManager = new LinearLayoutManager(this);
          mRecyclerView.setLayoutManager(mLayoutManager);
  
  
          mAdapter = new MyAdapter(recipes);
          mRecyclerView.setAdapter(mAdapter);
  
  
  
          //This button creates a new empty Recipe object and passes it to the EditRecipe class
          //The Recipe object is passed as a parcelable
          Button mCreateRecipeButton = (Button) findViewById(R.id.create_new_recipe_button);
          mCreateRecipeButton.setOnClickListener(new View.OnClickListener(){
              public void onClick(View v){
                  //Create a new empty recipe to be passed to the EditRecipe class
                  Recipe passedRecipe = new Recipe();
                  Intent i = new Intent(RecipeList.this, EditRecipe.class);
                  i.putExtra("passed_recipe_key", (Parcelable) passedRecipe);
                  startActivityForResult(i, REQUEST_CODE);
              }
          });
      }
  
      @Override
      protected void onSaveInstanceState(Bundle savedInstanceState){
          savedInstanceState.putParcelableArrayList("savedRecipes", recipes);
      }
  
      //protected void onRestoreInstanceState(Bundle)
  
      @Override
      protected void onResume(){
          super.onResume();
      }
  
      //This code is called after creating a new recipe. This is only for creating, and not editing.
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data){
          super.onActivityResult(requestCode, resultCode, data);
          if (requestCode == REQUEST_CODE){
              if(resultCode == Activity.RESULT_OK) {
                  Recipe editedRecipe = data.getExtras().getParcelable("recipe_key");
                  recipes.add(editedRecipe);
                  mAdapter.notifyDataSetChanged();
              }
          }
      }
  
      //This will be called from RecipeTextView after a user edits a recipe they chose. When a new reicpe is
      //created, the user returns here. When a recipe is edited, the user returns to that text view. But
      //The recipe still needs to be updated within this list (Yay consistency!)(Holy cow Google has spell check in comments...the future is now.)(Hire me I'm comical and write overly long comments.)
      protected void updateList(Recipe editedRecipe){
          for(Recipe recipe : recipes){
              if(recipe.getID().equals(editedRecipe.getID())){
                  int index = recipes.indexOf(recipe);
                  recipes.set(index, editedRecipe);
                  mAdapter.notifyDataSetChanged();
                  break;
              }
          }
  
      }
  }
  </code></pre>
  
  <p>And recipe class:</p>
  
  <pre><code>import android.os.Parcel;
  import android.os.Parcelable;
  
  import java.io.Serializable;
  import java.util.List;
  import java.util.UUID;
  
  /**
   * Created by Jacob on 9/14/2016.
   */
  //Implements serilizable so that it can be passed in a bundle as a serializable object
  public class Recipe implements Parcelable {
  
      //These are all of the qualities a recipe contains, we will create an arraylist of this in the activity
      private String mRecipeName;
      private UUID mID;
      private String mServings;
      private String mPrepTime;
      private String mCookTime;
  
      private List&lt;String&gt; mIngredients;
      private List&lt;String&gt; mDirections;
  
      public Recipe(){
          mID = UUID.randomUUID();
      }
  
      public String getRecipeName() {
          return mRecipeName;
      }
  
      public UUID getID() {
          return mID;
      }
  
      public String getServings() {
          return mServings;
      }
  
      public String getPrepTime() {
          return mPrepTime;
      }
  
  
      public void setRecipeName(String recipeName) {
          mRecipeName = recipeName;
      }
  
      public void setServingSize(String servings) {
          mServings = servings;
      }
  
      public void setPrepTime(String prepTime) {
          mPrepTime = prepTime;
      }
  
      public List&lt;String&gt; getIngredients() {
          return mIngredients;
      }
  
      public List&lt;String&gt; getDirections() {
          return mDirections;
      }
  
      public String getCookTime() {
          return mCookTime;
      }
  
      public void setCookTime(String cookTime) {
          mCookTime = cookTime;
      }
  
      public void setIngredients(List&lt;String&gt; ingredients) {
          mIngredients = ingredients;
      }
  
      public void setDirections(List&lt;String&gt; directions) {
          mDirections = directions;
      }
  
  
      @Override
      public int describeContents() {
          return 0;
      }
  
      @Override
      public void writeToParcel(Parcel dest, int flags) {
          dest.writeString(this.mRecipeName);
          dest.writeSerializable(this.mID);
          dest.writeString(this.mServings);
          dest.writeString(this.mPrepTime);
          dest.writeString(this.mCookTime);
          dest.writeStringList(this.mIngredients);
          dest.writeStringList(this.mDirections);
      }
  
      protected Recipe(Parcel in) {
          this.mRecipeName = in.readString();
          this.mID = (UUID) in.readSerializable();
          this.mServings = in.readString();
          this.mPrepTime = in.readString();
          this.mCookTime = in.readString();
          this.mIngredients = in.createStringArrayList();
          this.mDirections = in.createStringArrayList();
      }
  
      public static final Parcelable.Creator&lt;Recipe&gt; CREATOR = new Parcelable.Creator&lt;Recipe&gt;() {
          @Override
          public Recipe createFromParcel(Parcel source) {
              return new Recipe(source);
          }
  
          @Override
          public Recipe[] newArray(int size) {
              return new Recipe[size];
          }
      };
  }
  </code></pre>