Ive come in to a problem that has me completely stumped beyond belief. My custom object seems to be losing the values after it is sent via intent to a new activity. Why would an object lose values of its instance variables only after being passed with intent?
I have custom object that implements Parcelable, for storing specific data.
public class Vehicle implements Parcelable, Serializable{
private static final String TAG = "vehicleObject";
public String vehicleType;
public String refID;
public String title;
public HashMap<String, String> reservedSpecs;
public HashMap<String, String> generalSpecs;
public HashMap<String, String> engineSpecs;
public HashMap<String, String> powerTrainSpecs;
public HashMap<String, String> otherSpecs;
public Vehicle(String vehicleType, String year, String make, String model){
this.refID = UUID.randomUUID().toString();
this.title = year + " " + make + " " + model;
this.vehicleType = vehicleType;
this.reservedSpecs = new HashMap<>();
this.reservedSpecs.put("year", year);
this.reservedSpecs.put("make", make);
this.reservedSpecs.put("model", model);
}
public Vehicle(Parcel source){
Bundle bundle = source.readBundle(getClass().getClassLoader());
vehicleType = bundle.getString("vehicleType");
refID = bundle.getString("refID");
title = bundle.getString("title");
reservedSpecs = (HashMap) bundle.getSerializable("reserved");
generalSpecs = (HashMap) bundle.getSerializable("general");
engineSpecs = (HashMap) bundle.getSerializable("engine");
powerTrainSpecs = (HashMap) bundle.getSerializable("power");
otherSpecs = (HashMap) bundle.getSerializable("other");
}
@Override
public void writeToParcel(Parcel dest, int flags){
Bundle bundle = new Bundle();
bundle.putString("vehicleType", vehicleType);
bundle.putString("refID", refID);
bundle.putString("title", title);
bundle.putSerializable("reserved", reservedSpecs);
bundle.putSerializable("general", generalSpecs);
bundle.putSerializable("engine", engineSpecs);
bundle.putSerializable("power", powerTrainSpecs);
bundle.putSerializable("other", otherSpecs);
dest.writeBundle(bundle);
}
@Override
public int describeContents(){
return 0;
}
/**
*Generic getters/Setters for all instance variables
**/
/**
* Creator required for class implementing the parcelable interface.
*/
public static final Parcelable.Creator<Vehicle> CREATOR = new Creator<Vehicle>() {
@Override
public Vehicle createFromParcel(Parcel source) {
return new Vehicle(source);
}
@Override
public Vehicle[] newArray(int size) {
return new Vehicle[size];
}
};
}
I then, in my main activity, pass the object(Vehicle) using a listener. The object lives in ArrayList
public class fragment_overview extends Fragment implements UpdateUI{
private static final String TAG = "frg_ovrvw";
private final String SHARED_PREF = "com.kd8bny.maintenanceman_preferences";
private Toolbar toolbar;
private Context context;
private SharedPreferences sharedPreferences;
private RecyclerView cardList;
private RecyclerView.LayoutManager cardMan;
private RecyclerView.Adapter cardListAdapter;
private ArrayList<Vehicle> roster;
private String mUnit;
public fragment_overview() {
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
context = getActivity().getApplicationContext();
roster = new ArrayList<>(new SaveLoadHelper(context).load());
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_overview, container, false);
sharedPreferences = context.getSharedPreferences(SHARED_PREF, 0);
//Toolbar
toolbar = (Toolbar) view.findViewById(R.id.tool_bar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
((AppCompatActivity)getActivity()).getSupportActionBar().setHomeButtonEnabled(true);
//cards
mUnit = sharedPreferences.getString("prefUnitDist", "");
cardList = (RecyclerView) view.findViewById(R.id.overview_cardList);
cardMan = new LinearLayoutManager(getActivity());
cardList.setLayoutManager(cardMan);
cardList.addOnItemTouchListener(new RecyclerViewOnItemClickListener(context, cardList, new RecyclerViewOnItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int pos) {
if (!roster.isEmpty()) { //THIS INTENT HERE
Intent viewIntent = new Intent(getActivity(), test.class);
Bundle bundle = new Bundle();
bundle.putParcelable("vehicle", roster.get(pos));
bundle.putInt("pos", pos);
viewIntent.putExtra("bundle", bundle);
view.getContext().startActivity(viewIntent);
} else {
Intent addIntent = new Intent(getActivity(), activity_add_fleetRoster.class);
addIntent.putParcelableArrayListExtra("roster", roster);
view.getContext().startActivity(addIntent);
}
}
@Override
public void onItemLongClick(View view, int pos) {}}));
return view;
Once the intent is sent I receive it in my new activity.
public class test extends AppCompatActivity {
private ArrayList<Vehicle> roster;
private Vehicle vehicle;
RecyclerView cardList;
RecyclerView.LayoutManager cardMan;
RecyclerView.Adapter cardListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Bundle bundle = getIntent().getBundleExtra("bundle");
vehicle = bundle.getParcelable("vehicle");
int vehiclePos = bundle.getInt("pos", -1);
//Set recycler view
cardList = (RecyclerView) findViewById(R.id.info_cardList);
cardMan = new LinearLayoutManager(this);
cardList.setLayoutManager(cardMan);
}
@Override
public void onResume(){
super.onResume();
cardListAdapter = new adapter_info(vehicle);
cardList.setAdapter(cardListAdapter);
}
}
The adapter then takes the vehicle object and uses getters to generate cards
public adapter_info(Vehicle vehicle) {
ArrayList<HashMap> temp = new ArrayList<>();
temp.add(vehicle.getGeneralSpecs());
temp.add(vehicle.getEngineSpecs());
temp.add(vehicle.getPowerTrainSpecs());
temp.add(vehicle.getOtherSpecs());
}
/**
*Adapter stuff such as onCreateViewHodler and bind
**/
Now this all works fine and dandy the first run-through. When I Try to do anything after including sending this object through another intent, resuming the activity, anything using getters and setters on my object. The Hashmaps in my object lose their values
Below is a gif of what happens when you press recents and return to the app. The app never loses focus.
Here is a log showing what happens
01-09 20:27:19.850 2359-2359/com.kd8bny.maintenanceman D/TEST!!!: create{G=G}{E=E}{P=P}{Po=Oo} //All 4 hashmaps with values
01-09 20:27:19.850 2359-2359/com.kd8bny.maintenanceman A/getGeneralSpecs: get{G=G} //A log of each hashmap in the object's getter method
01-09 20:27:19.850 2359-2359/com.kd8bny.maintenanceman A/getEngineSpecs: get{E=E}
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman A/getPowerTrainSpecs: get{P=P}
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman A/getOtherSpecs: get{Po=Oo}
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{G=G}, {E=E}, {P=P}, {Po=Oo}] //Finally what the adapter sees using the getter method
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{G=G}, {E=E}, {P=P}, {Po=Oo}]
After this ran here is the object called again
01-09 20:28:13.382 2359-2359/com.kd8bny.maintenanceman A/getGeneralSpecs: get{} //Empty hashmap that had G=G
01-09 20:28:13.382 2359-2359/com.kd8bny.maintenanceman A/getEngineSpecs: get{} //Empty hashmap that had E=E
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman A/getPowerTrainSpecs: get{} //Empty hashmap that had P=P
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman A/getOtherSpecs: get{Po=Oo} //hashmap that retains its value
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{Po=Oo}] //And what the adapter sees as it calls on the object again
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{Po=Oo}]
Why are these value disappearing? Can I do this differently to fix the problem. I have tried using a singeton and passing serializable with the same results. Thanks in advance!