1

ive searched days here searching for a solution, but i cant find it. I have a Activity who send an object through activities. But, when the "readParcelable" begins, after a few objects the CastExceptionError appears, ive debugged several times this code, tried to replace objects, comment objects, nothing works. Here the code: All the classes implements Parcelable, writeToParcel, readFromParcel and CREATOR methods.

@Override
public void onClick(View v) {
       carregaDados();
       Intent myIntent = new Intent(ctx, Activity_VendaProduto.class);
       if (!logradouro.getText().toString().equals("")) {
           cliente.setEndereco(endereco); //nothing important here, just another object
           gerarVenda(); //who populates my "venda object with data"
           myIntent.putExtra("venda", venda);
       }
       startActivity(myIntent); 
    }
});

And here, the writeToParcel of this "Venda" object:

@Override
public void writeToParcel(Parcel dest, int flags) {

    dest.writeString(numeroContrato);
    dest.writeString(numeroProposta);
    dest.writeString(observacaoComplementar);
    dest.writeString(tipoVenda);
    dest.writeString(fidelidade);
    dest.writeString(hash);
    dest.writeString(oferta);

    dest.writeParcelable(visita, flags);
    dest.writeParcelable(midia, flags);
    dest.writeParcelable(tipoContratoVenda, flags);
    dest.writeParcelable(periodoInstalacao, flags);
    dest.writeParcelable(produtoAgrupamento, flags);
    dest.writeParcelable(formaPagamento, flags);
    dest.writeParcelable(vendaInternet, flags);

}

On this class, i have a constructor who calls the method: "readFromParcel" here the constructor:

private Venda(Parcel source) {
    readFromParcel(source);
}

And here is the readFromParcel method( ive checked several times the order of items on the write and this method)

 private void readFromParcel(Parcel in) {

        numeroContrato = in.readString();
        numeroProposta = in.readString();
        observacaoComplementar = in.readString();
        tipoVenda = in.readString();
        fidelidade = in.readString();
        hash = in.readString();
        oferta = in.readString();

        visita =  in.readParcelable(Visita.class.getClassLoader());
        midia = in.readParcelable(Midia.class.getClassLoader());
        tipoContratoVenda = in.readParcelable(TipoContratoVenda.class.getClassLoader());
        periodoInstalacao = in.readParcelable(Periodo.class.getClassLoader());
        produtoAgrupamento = in.readParcelable(ProdutoAgrupamento.class.getClassLoader());
        formaPagamento = in.readParcelable(FormaPagamento.class.getClassLoader());
        vendaInternet =     in.readParcelable(VendaInternet.class.getClassLoader());
    }

All this readParcelable methods belongs to a custom object, and these objects class implements Parcelable and all of his methods as well.

here the LogCat error, occurs on this line:

            periodoInstalacao = in.readParcelable(Periodo.class.getClassLoader());
        produtoAgrupamento = in.readParcelable(ProdutoAgrupamento.class.getClassLoader());

Ive tried to comment , replace, but the error persists on the adjacent objects.

Logcat:

12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime  FATAL EXCEPTION: main
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime  java.lang.RuntimeException: Unable to start activity ComponentInfo{projetoTeste/projetoTeste.controle.Activity_VendaProduto}: java.lang.ClassCastException: projetoTeste.dto.Periodo cannot be cast to projetoTeste.dto.ProdutoAgrupamento
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.ActivityThread.access$600(ActivityThread.java:123)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.os.Handler.dispatchMessage(Handler.java:99)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.os.Looper.loop(Looper.java:137)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.ActivityThread.main(ActivityThread.java:4424)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at java.lang.reflect.Method.invokeNative(Native Method)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at java.lang.reflect.Method.invoke(Method.java:511)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at dalvik.system.NativeStart.main(Native Method)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime  Caused by: java.lang.ClassCastException: projetoTeste.dto.Periodo cannot be cast to projetoTeste.dto.ProdutoAgrupamento
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at projetoTeste.dto.Venda.readFromParcel(Venda.java:343)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at projetoTeste.dto.Venda.<init>(Venda.java:69)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at projetoTeste.dto.Venda.<init>(Venda.java:12)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at projetoTeste.dto.Venda$1.createFromParcel(Venda.java:349)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at projetoTeste.dto.Venda$1.createFromParcel(Venda.java:347)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.os.Parcel.readParcelable(Parcel.java:1992)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.os.Parcel.readValue(Parcel.java:1854)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.os.Parcel.readMapInternal(Parcel.java:2094)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.os.Bundle.unparcel(Bundle.java:223)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.os.Bundle.getParcelable(Bundle.java:1158)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at projetoTeste.controle.Activity_VendaProduto.onCreate(Activity_VendaProduto.java:79)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.Activity.performCreate(Activity.java:4465)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
12:20:22.493    526 projetoTeste    ERROR   AndroidRuntime      ... 11 more

So, i came here to beg a light, ive tried and tried and cannot see where and why this error still occurs.

Thanks in advance!

--- UPDATE ---

Solved, ive followed the steps of the answer, fixed some conversions/write/read on Lists and Arrays and everythings looks to works fine now! Thanks!

krustbr
  • 13
  • 1
  • 4
  • Try to replace all getClassLoader() arguments to null, e.g. tipoContratoVenda = in.readParcelable(null); for all Parcelable objects. – Yaroslav Mytkalyk May 28 '13 at 12:51
  • what is the type of periodoInstalacao and produtoAgrupamento? – mromer May 28 '13 at 12:53
  • produtoAgrupamento is a ProdutoAgrupamento object and periodoInstalacao a Periodo class (both implements Parcelable and methods, but inside ProdutoAgrupamento class i have a : "private ProdutoTipo[] tipoProdutoLista;" this list, dont know if is this guy causing this error, i dont think so, cause even when i comment the produtoAgrupamento, the cast error still occurs with the subjacent object on the read method – krustbr May 28 '13 at 12:55
  • And replacing classLoader with null i get on the first (null) object: ERROR AndroidRuntime Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: projetoTeste.dto.Visita .. and: ERROR AndroidRuntime Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: projetoTeste.dto.Visita – krustbr May 28 '13 at 12:59
  • Dont know if helps, but here my "Periodo" class: http://pastebin.com/2umQSxx4 And here my produtoAgrupamento class: http://pastebin.com/LzYKN0rF – krustbr May 28 '13 at 13:04

1 Answers1

3

Just for proper code style, Add generic types to CREATOR to all Parcelable objects. For Periodo, it should be

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

You don't need to do

if(tipoProdutoLista != null){
    for(int i=0; i < tipoProdutoLista.length;++i){
        parcelableTipoProduto[i] = (Parcelable) tipoProdutoLista[i];
    }
    dest.writeParcelableArray(parcelableTipoProduto, flags);
}

Just pass tipoProdutoLista as is, it is already Parcelable, and remove flags.

dest.writeParcelableArray(tipoProdutoLista, 0);

The error is, that you must not add the same flag that you got as writeToParcel argument when writing to Parcelable.

Replace flags when calling writeParcelable with zero

Was

dest.writeParcelable(visita, flags);

Should be

dest.writeParcelable(visita, 0);

Replace it in all places where you have writeParcelable call.

Yaroslav Mytkalyk
  • 16,950
  • 10
  • 72
  • 99
  • Im doing the changes, but ive used this for to the list because when i try to use writeParcelableArray i get: `code` method writeParcelableArray in class Parcel cannot be applied to given types; required: T[],int found: List,int reason: no instance(s) of type variable(s) T exist so that argument type List conforms to formal parameter type T[] where T is a type-variable: T extends Parcelable declared in method writeParcelableArray(T[],int)` – krustbr May 28 '13 at 13:27
  • And also cannot cast on: produtoList = in.readParcelableArray(Produto.class.getClassLoader()); cause of found Parcelable[] instead of Produto[], and casting with (Produto) didnt work. – krustbr May 28 '13 at 13:46
  • Ive changed all classes for generics types on CREATOR, and changed flags for 0 on writeParcelable methods. (Commented the parcelable list cause of the error on the previous comment) Same lines/error: `java.lang.RuntimeException: Unable to start activity ComponentInfo{projetoTeste/projetoTeste.controle.Activity_VendaProduto}: java.lang.ClassCastException: projetoTeste.dto.Periodo cannot be cast to projetoTeste.dto.ProdutoAgrupamento Caused by: java.lang.ClassCastException: projetoTeste.dto.Periodo cannot be cast to projetoTeste.dto.ProdutoAgrupamento` – krustbr May 28 '13 at 14:02
  • Ive commented this "periodo" guy, this what the new error looks like: `ERROR AndroidRuntime java.lang.RuntimeException: Unable to start activity ComponentInfo{projetoTeste/projetoTeste.controle.Activity_VendaProduto}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: ` And: `ERROR AndroidRuntime Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling:` – krustbr May 28 '13 at 14:12
  • And logcat point to this guy on produtoAgrupamento class: `parcelableTipoProduto = in.readParcelableArray(ProdutoTipo.class.getClassLoader());` – krustbr May 28 '13 at 14:12
  • Does Produto implements Parcelable? – Yaroslav Mytkalyk May 28 '13 at 14:54
  • Yes, Produto, ProdutoTipo, all these guys implements parcelables, and now with Generic CREATOR methods, let me know if i can provide any other code to clarify the problem – krustbr May 28 '13 at 15:33
  • Thanks, you actually helped me with the creator comments when I tried to cast subclass to the class. overiding the creator function solve the cast error. – Ido Apr 16 '15 at 22:43