3

In two situations, only one of them gives me this unique error. I pretty much followed the Android Tutorial character for character, and for some reason it only works in certain areas.

 Intent shareIntent = new Intent();
 shareIntent.setAction(Intent.ACTION_SEND);
 shareIntent.putExtra(Intent.EXTRA_TEXT, getSharedNutritionText(mMultiSelector.getSelectedPositions()));
 shareIntent.setType("text/plain");
 startActivity(shareIntent);

Gives the following error:

    12-13 02:10:07.838    8261-8261/com.example E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.skylan.homeworkpro, PID: 8261
java.lang.RuntimeException: Parcel: unable to marshal value com.example.NutritionInfo@2d54b4d1
        at android.os.Parcel.writeValue(Parcel.java:1343)
        at android.os.Parcel.writeList(Parcel.java:717)
        at android.os.Parcel.writeValue(Parcel.java:1290)
        at android.os.Parcel.writeArrayMapInternal(Parcel.java:644)
        at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313)
        at android.os.Bundle.writeToParcel(Bundle.java:1034)
        at android.os.Parcel.writeBundle(Parcel.java:669)
        at android.app.FragmentState.writeToParcel(Fragment.java:138)
        at android.os.Parcel.writeTypedArray(Parcel.java:1197)
        at android.app.FragmentManagerState.writeToParcel(FragmentManager.java:376)
        at android.os.Parcel.writeParcelable(Parcel.java:1363)
        at android.os.Parcel.writeValue(Parcel.java:1268)
        at android.os.Parcel.writeArrayMapInternal(Parcel.java:644)
        at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313)
        at android.os.Bundle.writeToParcel(Bundle.java:1034)
        at android.os.Parcel.writeBundle(Parcel.java:669)
        at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2925)
        at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3299)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5257)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Whereas in another one of my (almost) identical fragments, I have the following code:

 Intent shareIntent = new Intent();
 shareIntent.setAction(Intent.ACTION_SEND);
 shareIntent.putExtra(Intent.EXTRA_TEXT, getSharedLabelText(mMultiSelector.getSelectedPositions())); 
 shareIntent.setType("text/plain");
 startActivity(shareIntent);

Here's my NutritionInfo Class

public class NutritionInfo extends SugarRecord<NutritionInfo> {

public String nutritionName;
public String nutritionHeaderTitle;
public int nutritionCalories;
public boolean nutritionArchived;
public boolean nutritionChecked;

public NutritionInfo () {}

public NutritionInfo (String name, String headerTitle, int cal, boolean isArchived, boolean isChecked) {
    nutritionName = name;
    nutritionHeaderTitle = headerTitle;
    nutritionCalories = cal;
    nutritionArchived = isArchived;
    nutritionChecked = isChecked;
    }
}

Here's my Nutrition getter:

public class NutritionDisplayFragment extends BaseFragment implements ActionMode.Callback {
private String getSharedNutritionText(List<Integer> positions) {
    String shareText;
    if (positions.equals(null)) {
        shareText = "";
    } else {
        shareText = "Food and carbs:\n";
        for (int go = 0; go < positions.size(); go++) {
            shareText = shareText +
                    nutritionList.get(go).nutritionTitle + " - \t" +
                    nutritionList.get(go).nutritionCarbs + "\n";
        }
    }
    return shareText;
} ( . . . )
}

vs my Label getter:

public class LabelManagerFragment extends BaseFragment implements ActionMode.Callback {    
private String getSharedLabelText(List<Integer> positions) {
    String shareText = "";
    if (positions.equals(null)) {
        shareText = "";
    } else {
        for (int go = 0; go < positions.size(); go++) {
            shareText = shareText +
                        labelList.get(go).labelName + "\t" +
                        labelList.get(go).labelYear + "\n";
        }
    }
    return shareText;
} ( . . . )
}

And this gives no runtime error. Both get() methods return a simple string. Why does the first error complain about "com.package.NutritionInfo@84055e1", which isn't even the type of data being shared, as un-marshal-able and the other shares the string without a hitch?

For further clarity: I tried hardcoding "hello world" in for where the method is (the method that usually returns a simple String), and had the same issue.

AlleyOOP
  • 1,536
  • 4
  • 20
  • 43
  • Post your code of nutrition class with the parceling stuff. – Thomas R. Dec 14 '15 at 10:14
  • Added whatever I could find to be pertinent. – AlleyOOP Dec 14 '15 at 10:26
  • 2
    But the error seems to be related to the parcel stuff. Maybe you try to set a null value. That is the reason why I want to see the parcel stuff. – Thomas R. Dec 14 '15 at 11:24
  • Sorry, I don't quite understand. I, too, am trying to understand what exactly is being parcelled, but I cannot figure it out. I don't understand why it is trying to marshal what it seems is a NutritionInfo object, if that is indeed what it is trying to parcel. Please clarify what I should post for code and I will deliver. – AlleyOOP Dec 14 '15 at 17:26
  • Can you post the full stack trace? I thought you try to parcel the NutritionInfo, but it seems not. – Thomas R. Dec 15 '15 at 13:45
  • Yes, I've included the full stack trace now. – AlleyOOP Dec 15 '15 at 17:08
  • Does your Nutrition class implements Parceleable? Post your NutritionInfo class. – cgr Dec 15 '15 at 17:17
  • updated. It doesn't implement anything, nor is what is being sent a NutritionInfo object. Is that even what "com.package.NutritionInfo@84055e1" is saying? That I am trying to parcel a NutritionInfo object? Because even when I hardcode a string in for the value, it gives the same error (only in that situation - not for Label) – AlleyOOP Dec 15 '15 at 17:56
  • As `NutritionInfo` is not directly implementing `Parcelable`, `SugarRecord` probably does. The code of the base class implementing it would be useful. – Marc Plano-Lesay Dec 15 '15 at 17:57
  • I don't understand, why would hardcoding "hello world" in for the intent shared text give the same error though? In other words, why would we believe that NutritionInfo is the reason for the error? – AlleyOOP Dec 15 '15 at 18:00
  • 1
    For some reason, the `Fragment` (I guess) is trying to serialize a `NutritionInfo` object (maybe when it's trying to save its instance?). Which is not possible (either `NutritionInfo` isn't serializable or parcelable, or something is wrong in the serialization process). Check http://stackoverflow.com/q/3818745/775894 for example. – Marc Plano-Lesay Dec 15 '15 at 18:08
  • you recommend implementing Parcelable or Serializable and trying from there? – AlleyOOP Dec 15 '15 at 19:40
  • That is what I already asked, if your NutritionInfo implements Parcelable. But the super class should also be Parcelable. – Thomas R. Dec 16 '15 at 07:34
  • Neither implements Parcelable. NutritionInfo is included above. If both need to be Parcelable, and that is the answer, then we have solved the issue, but either way, neither seems to be the answer to why those classes are trying to be "marshal"ed to begin with, especially when neither is involved in the ACTION_SHARE event (at least explicitly) – AlleyOOP Dec 16 '15 at 07:39

1 Answers1

1

Implement the Parcelable interface like follows:

public class NutritionInfo extends SugarRecord<NutritionInfo> implements Parcelable {

  public String nutritionName;
  public String nutritionHeaderTitle;
  public int nutritionCalories;
  public boolean nutritionArchived;
  public boolean nutritionChecked;

  public NutritionInfo() {
  }

  public NutritionInfo(String name, String headerTitle, int cal, boolean isArchived, boolean isChecked) {
    nutritionName = name;
    nutritionHeaderTitle = headerTitle;
    nutritionCalories = cal;
    nutritionArchived = isArchived;
    nutritionChecked = isChecked;
  }

  protected NutritionInfo(Parcel in) {
    nutritionName = (String) in.readValue(null);
    nutritionHeaderTitle = (String) in.readValue(null);
    nutritionCalories = in.readInt();
    nutritionArchived = in.readByte() != 0;
    nutritionChecked = in.readByte() != 0;
  }

  public static final Creator<NutritionInfo> CREATOR = new Creator<NutritionInfo>() {
    @Override
    public NutritionInfo createFromParcel(Parcel in) {
        return new NutritionInfo(in);
    }

    @Override
    public NutritionInfo[] newArray(int size) {
        return new NutritionInfo[size];
    }
  };

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeValue(nutritionName);
    dest.writeValue(nutritionHeaderTitle);
    dest.writeInt(nutritionCalories);
    dest.writeByte((byte) (nutritionArchived ? 1 : 0));
    dest.writeByte((byte) (nutritionChecked ? 1 : 0));
  }
}

Do the same for your sugar record. And if the super class implements Parcelable you do not need to declare again in NutritionInfo, only implement the stuff.

Thomas R.
  • 7,988
  • 3
  • 30
  • 39