Tintinabulator Zea
Tintinabulator Zea

Reputation: 2807

getParcelableArrayList returns a Parcelable but i need it to return my object. (java android)

I got an error as below:

Error:(133, 15) error: method setMonkeyBuisness in class QuoteBank cannot be applied to given types;
required: ArrayList<QuoteQuestion>
found: ArrayList<Parcelable>
reason: actual argument ArrayList<Parcelable> cannot be converted to     
ArrayList<QuoteQuestion> by method invocation conversion

Both QuoteQuestion and QuoteBank implement Parcelable and all their methods. I cannot type cast parcelable either.

Am I using Parcelable array list correctly?

Here is some part of my code for QuoteBank:

public class QuoteBank implements Parcelable{
    public static final String ARRAY_LIST_KEY = "arrayListKey";
    private ArrayList<QuoteQuestion> monkeyBuisness;


    public QuoteBank(){
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Bundle bundle = new Bundle();

        bundle.putParcelableArrayList(ARRAY_LIST_KEY, monkeyBuisness);

        dest.writeBundle(bundle);
    }

    public static final Parcelable.Creator<QuoteBank> CREATOR = new Creator<QuoteBank>() {

        @Override
        public QuoteBank createFromParcel(Parcel source) {

            Bundle bundle = source.readBundle();
            QuoteBank qb = new QuoteBank();
            qb.setMonkeyBuisness(bundle.getParcelableArrayList(ARRAY_LIST_KEY));

            return qb;
        }

    public void setMonkeyBuisness(ArrayList<QuoteQuestion> monkeyBuisness) {
        this.monkeyBuisness = monkeyBuisness;
    }

Here is QuoteQuestion code:

public class QuoteQuestion implements Parcelable{
public static final String QUOTE_TYPE = "quoteType";
public static final String QUOTE_NUMBER = "quoteNumber";
public static final String QUOTE_ARRAY = "quoteArray";
public static final String SPEAKER_ARRAY = "speakerArray";
public static final String ANSWER_INDEX_ARRAY = "answerIndexArray";
public static final String ANSWER_CHOICE_ARRAY = "answerChoiceArray";
public static final String CONTEXT_KEY = "contextKey";
public static final String CHOSEN_ANSWER = "chosenAnswer";
public static final String WORD_SPLIT = "wordSplit";
private int quoteNumber;
private String quoteType;
private ArrayList<String> quote;
private ArrayList<String> speaker;
private ArrayList<Integer> answerIndex;
private ArrayList<String> answerChoice;
private String context;
private String chosenAnswer;

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    Bundle bundle = new Bundle();

    // insert the key value pairs to the bundle

    bundle.putInt(QUOTE_NUMBER, quoteNumber);
    bundle.putString(QUOTE_TYPE, quoteType);
    bundle.putStringArrayList(QUOTE_ARRAY, quote);
    bundle.putStringArrayList(SPEAKER_ARRAY, speaker);
    bundle.putIntegerArrayList(ANSWER_INDEX_ARRAY, answerIndex);
    bundle.putStringArrayList(ANSWER_CHOICE_ARRAY, answerChoice);
    bundle.putString(CONTEXT_KEY, context);
    bundle.putString(CHOSEN_ANSWER, chosenAnswer);
    bundle.putStringArrayList(WORD_SPLIT, wordSplitTypeA);

    // write the key value pairs to the parcel
    dest.writeBundle(bundle);

}

public static final Parcelable.Creator<QuoteQuestion> CREATOR = new Creator<QuoteQuestion>() {

    @Override
    public QuoteQuestion createFromParcel(Parcel source) {
        // read the bundle containing key value pairs from the parcel
        Bundle bundle = source.readBundle();
        QuoteQuestion quoteQuestion = new QuoteQuestion();

        quoteQuestion.setQuoteNumber(bundle.getInt(QUOTE_NUMBER));
        quoteQuestion.setQuoteType(bundle.getString(QUOTE_TYPE));
        quoteQuestion.setQuote(bundle.getStringArrayList(QUOTE_ARRAY));
        quoteQuestion.setSpeaker(bundle.getStringArrayList(SPEAKER_ARRAY));
        quoteQuestion.setAnswerIndex(bundle.getIntegerArrayList(ANSWER_INDEX_ARRAY));
        quoteQuestion.setAnswerChoice(bundle.getStringArrayList(ANSWER_CHOICE_ARRAY));
        quoteQuestion.setContext(bundle.getString(CONTEXT_KEY));
        quoteQuestion.setChosenAnswer(bundle.getString(CHOSEN_ANSWER));
        quoteQuestion.setWordSplitTypeA(bundle.getStringArrayList(WORD_SPLIT));

        return quoteQuestion;
    }

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

};

Also I have a second question while here - It seems all big multi UI apps will have almost all classes implement parcelable? as it is the only way to get data around the app? Is this best practice?

Upvotes: 1

Views: 5660

Answers (2)

arekolek
arekolek

Reputation: 9621

It should suffice to write:

qb.setMonkeyBuisness(bundle.<QuoteQuestion>getParcelableArrayList(ARRAY_LIST_KEY));

Upvotes: 0

Jeremy Frank
Jeremy Frank

Reputation: 763

Split your statement into two, using a variable to hold the properly-typed ArrayList, like this:

ArrayList<QuoteQuestion> qq = bundle.getParcelableArrayList(ARRAY_LIST_KEY);
qb.setMonkeyBuisness(qq);

Why this works, whereas casting does not? I have no idea. If anyone knows, please replace this paragraph!

As for the second question, about implementing Parcelable all over the place: The temporary-by-design nature of all Activities and heavy usage of Intents can lead to requiring Parcelable in many places. Certain app design patterns can help mitigate the problem. For example, following MVC techniques, your application data can live within the Model, accessible via a custom class derived from Application. This allows most Activities to avoid saving & restoring bundled data, as they are simply Views of the Model, which persists across device rotations etc. This is a much bigger topic of course, with many different approaches, but hopefully this sparks some ideas.

Upvotes: 3

Related Questions