Whenever I try to pass information between 2 activities by using intent, my app crashes and gives me this exception:
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.poop123.FoodItem)
I can't possibly find a thread with an answer that resolves my issue.
foodLibrary.class
package com.example.poop123;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultCaller;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
import com.gigamole.navigationtabstrip.NavigationTabStrip;
import java.io.Serializable;
import java.util.ArrayList;
public class foodLibrary extends AppCompatActivity implements Serializable{
ArrayList<FoodItem> foodItems = new ArrayList<>();
boolean itemsExist = false;
RecyclerView rv;
ImageView closeArrow;
ImageView addItem;
FoodItem item;
ActivityResultLauncher<Intent> activityLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == 78) {
Intent intent = result.getData();
if (intent != null) {
item = (FoodItem) intent.getSerializableExtra("123");
}
}
}
}
);
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.create_foods_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.addFood:
Toast.makeText(this, "Yooo", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_library);
rv = findViewById(R.id.recycler);
closeArrow = findViewById(R.id.arrow_foods);
addItem = findViewById(R.id.add_button);
Intent i = getIntent();
item = (FoodItem) i.getSerializableExtra("123");
if (itemsExist) {
generateRecycler(item);
adapterConnect();
} else {
itemsExist = true;
}
closeArrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
addItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openMenu();
}
});
}
private void generateRecycler(FoodItem item) {
foodItems.add(item);
}
private void adapterConnect() {
FoodRecyclerAdapter adapter = new FoodRecyclerAdapter(getApplicationContext(), item ,foodItems);
rv.setAdapter(adapter);
rv.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
}
private void openMenu() {
PopupMenu popup = new PopupMenu(this, addItem);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.create_foods_menu, popup.getMenu());
popup.show();
}
public void openNewFoodMenu (MenuItem item){ // ONCLICKLISTENER ESTÁ NO FICHEIRO XML
Intent intent = new Intent(foodLibrary.this, newFoodMenu.class);
activityLauncher.launch(intent);
}
}
newFoodMenu.class
package com.example.poop123;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.io.Serializable;
public class newFoodMenu extends AppCompatActivity implements SingleChoiceDialog.SingleChoiceListener, Serializable {
ImageView closeButton;
TextView measurementSelector;
RelativeLayout saveButton;
String asterisco;
public String sDescription; public String sBrand; public String sBarcode; public String sServing; public String sMeasurement; public String sCalories; public String sFat; public String sCarbohydrate; public String sProtein;
public EditText eDescription; public EditText eBrand; public EditText eBarcode; public EditText eServing; public EditText eCalories; public EditText eFat; public EditText eCarbohydrate; public EditText eProtein;
public TextView tDescription;
public TextView tBrand;
public TextView tBarcode;
public TextView tServing;
public TextView tMeasurement;
public TextView tCalories;
public TextView tFat;
public TextView tCarbohydrate;
public TextView tProtein;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_food_menu);
closeButton = findViewById(R.id.close_button);
saveButton = findViewById(R.id.button_save);
eDescription = (EditText) findViewById(R.id.etDescription);
eBrand = (EditText) findViewById(R.id.etBrand);
eBarcode = (EditText) findViewById(R.id.etBarcode);
measurementSelector = findViewById(R.id.measurementUnitsSelector);
eServing = (EditText) findViewById(R.id.etServing);
eCalories = (EditText) findViewById(R.id.etCalories);
eFat = (EditText) findViewById(R.id.etFat);
eCarbohydrate = (EditText) findViewById(R.id.etCarbohydrate);
eProtein = (EditText) findViewById(R.id.etProtein);
tDescription = (TextView) findViewById(R.id.tvDescription);
tBrand = (TextView) findViewById(R.id.tvBrand);
tBarcode = (TextView) findViewById(R.id.tvBarcode);
tServing = (TextView) findViewById(R.id.tvServing);
tMeasurement = (TextView) findViewById(R.id.tvMeasurement);
tCalories = (TextView) findViewById(R.id.tvCalories);
tFat = (TextView) findViewById(R.id.tvFat);
tCarbohydrate = (TextView) findViewById(R.id.tvCarbohydrate);
tProtein = (TextView) findViewById(R.id.tvProtein);
asterisco = "*";
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
measurementSelector.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogFragment scd = new SingleChoiceDialog();
scd.setCancelable(false);
scd.show(getSupportFragmentManager(), "Single Choice Dialog");
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sDescription = eDescription.getText().toString();
sBrand = eBrand.getText().toString();
sBarcode = eBarcode.getText().toString();
sServing = eServing.getText().toString();
sCalories = eCalories.getText().toString();
sFat = eFat.getText().toString();
sCarbohydrate = eCarbohydrate.getText().toString();
sProtein = eProtein.getText().toString();
verifyFields();
}
});
}
private void createItem(String description, String brand, String serving, String calories, String carbohydrates, String protein, String fats, TextView selector) {
FoodItem item = new FoodItem(description, brand, serving, calories, carbohydrates, protein, fats, selector);
Intent intent = new Intent();
intent.putExtra("123", item);
setResult(78, intent);
finish();
}
public void verifyFields() {
if (checkEmpty()) {
if (sDescription.isEmpty()) {
fieldStatusWrong(tDescription, "Description*");
} else if (!sDescription.isEmpty()) {
fieldStatusCorrect(tDescription, "Description");
}
if (sServing.isEmpty()) {
fieldStatusWrong(tServing, "By serving of*");
} else if (!sServing.isEmpty()) {
fieldStatusCorrect(tServing, "By serving of");
}
if (sCalories.isEmpty()) {
fieldStatusWrong(tCalories, "Calories (kcal)*");
} else if (!sCalories.isEmpty()) {
fieldStatusCorrect(tCalories, "Calories (kcal)");
}
if (sFat.isEmpty()) {
fieldStatusWrong(tFat, "Fat (g)*");
} else if (!sFat.isEmpty()) {
fieldStatusCorrect(tFat, "Fat (g)");
}
if (sCarbohydrate.isEmpty()) {
fieldStatusWrong(tCarbohydrate, "Carbohydrate (g)*");
} else if (!sCarbohydrate.isEmpty()) {
fieldStatusCorrect(tCarbohydrate, "Carbohydrate (g)");
}
if (sProtein.isEmpty()) {
fieldStatusWrong(tProtein, "Protein (g)*");
} else if (!sProtein.isEmpty()) {
fieldStatusCorrect(tProtein, "Protein (g)");
}
} if (!checkEmpty()) {
createItem(sDescription, sBrand, sServing, sCalories, sFat, sCarbohydrate, sProtein, measurementSelector);
}
}
private void fieldStatusWrong(TextView t, String text) {
if (t.getText().toString().equals(text)) {
t.setTextColor(Color.parseColor("#ff0000"));
} else {
t.setTextColor(Color.parseColor("#ff0000"));
t.setText(text);
}
}
private void fieldStatusCorrect(TextView t, String text) {
if (t.getText().toString().equals(text)) {
t.setTextColor(Color.parseColor("#C2C2C2"));
} else {
t.setTextColor(Color.parseColor("#C2C2C2"));
t.setText(t.getText().toString().substring(0, t.length()-1));
}
}
private boolean checkEmpty() {
if (sDescription.isEmpty() || sServing.isEmpty() || sCalories.isEmpty() || sFat.isEmpty() || sCarbohydrate.isEmpty() || sProtein.isEmpty()) {
return true;
}
return false;
}
@Override
public void onPositiveButtonClicked(String[] list, int position) {
measurementSelector.setText(list[position]);
}
@Override
public void onNegativeButtonClicked() {
}
}
FoodItem.class
package com.example.poop123;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.io.Serializable;
public class FoodItem implements Serializable {
String description, brand, serving, calories, carbohydrates, protein, fats;
TextView measurementUnit;
public FoodItem(String description, String brand, String serving, String calories, String carbohydrates, String protein, String fats, TextView measurementUnit) {
this.description = description;
this.brand = brand;
this.serving = serving;
this.calories = calories;
this.carbohydrates = carbohydrates;
this.protein = protein;
this.fats = fats;
this.measurementUnit = measurementUnit;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getServing() {
return serving;
}
public void setServing(String serving) {
this.serving = serving;
}
public String getCalories() {
return calories;
}
public void setCalories(String calories) {
this.calories = calories;
}
public String getCarbohydrates() {
return carbohydrates;
}
public void setCarbohydrates(String carbohydrates) {
this.carbohydrates = carbohydrates;
}
public String getProtein() {
return protein;
}
public void setProtein(String protein) {
this.protein = protein;
}
public String getFats() {
return fats;
}
public void setFats(String fats) {
this.fats = fats;
}
public TextView getMeasurementUnit() {
return measurementUnit;
}
public void setMeasurementUnit(TextView measurementUnit) {
this.measurementUnit = measurementUnit;
}
}
FULL error message
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.poop123, PID: 23203
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.poop123.FoodItem)
at android.os.Parcel.writeSerializable(Parcel.java:2113)
at android.os.Parcel.writeValue(Parcel.java:1883)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:975)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1044)
at android.content.Intent.writeToParcel(Intent.java:10855)
at android.app.IActivityTaskManager$Stub$Proxy.finishActivity(IActivityTaskManager.java:4260)
at android.app.Activity.finish(Activity.java:6376)
at android.app.Activity.finish(Activity.java:6412)
at com.example.poop123.newFoodMenu.createItem(newFoodMenu.java:120)
at com.example.poop123.newFoodMenu.verifyFields(newFoodMenu.java:165)
at com.example.poop123.newFoodMenu$3.onClick(newFoodMenu.java:104)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.io.NotSerializableException: com.google.android.material.textview.MaterialTextView
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
at android.os.Parcel.writeSerializable(Parcel.java:2108)
at android.os.Parcel.writeValue(Parcel.java:1883)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:975)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1044)
at android.content.Intent.writeToParcel(Intent.java:10855)
at android.app.IActivityTaskManager$Stub$Proxy.finishActivity(IActivityTaskManager.java:4260)
at android.app.Activity.finish(Activity.java:6376)
at android.app.Activity.finish(Activity.java:6412)
at com.example.poop123.newFoodMenu.createItem(newFoodMenu.java:120)
at com.example.poop123.newFoodMenu.verifyFields(newFoodMenu.java:165)
at com.example.poop123.newFoodMenu$3.onClick(newFoodMenu.java:104)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
DontReadThisTextJustFillingInSoStackOverflowAllowsMeToPostThisQuestionAsIHaveProvidedEnoughInformationAlready