Android: Parcelable: класс не найден при отмене сортировки - PullRequest
0 голосов
/ 04 декабря 2018

У меня вопрос по поводу parcelable.
Моя структура дизайна приложения выглядит следующим образом:

  • У меня есть один основной класс A, у которого есть массив ParentB.
  • Класс ParentB является абстрактным классом и имеетабстрактные методы.
  • Классы ChildB1 и ChildB2 являются дочерними классами класса ParentB.
  • Класс ParentB имеет массив данных класса C.
  • Класс C имеет класс D в качестве атрибута
  • Все классы реализуют Parcelable.

Эта структура проекта полезна, когда я отправляю данные из одного занятия в другое занятие с использованием намерения или одного фрагмента в другой фрагмент с использованием связки.Ниже приведена моя структура проектирования классов POJO:

Это класс A

 import android.os.Parcel;
    import android.os.Parcelable;

    import java.util.ArrayList;

    public class A implements Parcelable {

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

            @Override
            public A createFromParcel(Parcel source) {
                return new A(source);
            }

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

        private String name;
        private String details;
        private ArrayList<ParentB> parentBList; //ParentB List


        private A(Parcel parcel)
        {
            this.name = parcel.readString();
            this.details = parcel.readString();
            this.parentBList = parcel.createTypedArrayList(ParentB.CREATOR);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDetails() {
            return details;
        }

        public void setDetails(String details) {
            this.details = details;
        }

        public ArrayList<ParentB> getParentBList() {
            return parentBList;
        }

        public void setParentBList(ArrayList<ParentB> parentBList) {
            this.parentBList = parentBList;
        }

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

        @Override
        public void writeToParcel(Parcel parcel, int i) {
            parcel.writeString(name);
            parcel.writeString(details);
            parcel.writeTypedList(parentBList);
        }
    }

Это абстрактный класс ParentB:

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;

public abstract class ParentB implements Parcelable {

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

        @Override
        public ParentB createFromParcel(Parcel source) {
            return getClassType(source);
        }

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

    private String className;
    private String name;
    private String details;
    private ArrayList<C> cList; //ParentC List


    protected ParentB(Parcel parcel)
    {
        this.className = parcel.readString();
        this.name = parcel.readString();
        this.details = parcel.readString();
        this.cList = parcel.createTypedArrayList(C.CREATOR);
    }

    public String getClassName() {
        return className;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public ArrayList<C> getCList() {
        return cList;
    }

    public void setCList(ArrayList<C> CList) {
        this.cList = CList;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(className);
        parcel.writeString(name);
        parcel.writeString(details);
        parcel.writeTypedList(cList);
    }

    public static ParentB getClassType(Parcel parcel)
    {
        switch (parcel.readString())
        {
            case "ChildB1" :
                return new ChildB1(parcel);

            case "ChildB2" :
                return new ChildB2(parcel);

            default:
                return new ChildB2(parcel);
        }
    }

}

Этот класс ChildB1 расширяется от ParentB

import android.os.Parcel;
import android.os.Parcelable;

public class ChildB1 extends ParentB
{

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

        @Override
        public ChildB1 createFromParcel(Parcel source) {
            return new ChildB1(source);
        }

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


    private int value;

    protected ChildB1(Parcel parcel) {
        super(parcel);
        this.value = parcel.readInt();
    }


    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        super.writeToParcel(parcel, i);
        parcel.writeInt(value);
    }
}

Этот класс ChildB2 расширяется от ParentB

import android.os.Parcel;
import android.os.Parcelable;

public class ChildB2 extends ParentB
{
    public static final Parcelable.Creator<ChildB2> CREATOR = new Parcelable.Creator<ChildB2>() {

        @Override
        public ChildB2 createFromParcel(Parcel source) {
            return new ChildB2(source);
        }

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


    public ChildB2(Parcel parcel) {
        super(parcel);
    }

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

Это класс C

import android.os.Parcel;
import android.os.Parcelable;

public class C implements Parcelable
{

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

        @Override
        public C createFromParcel(Parcel source) {
            return new C(source);
        }

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

    private String name;
    private String details;
    private D d;

    public C(Parcel parcel)
    {
        this.name = parcel.readString();
        this.details = parcel.readString();
        this.d = parcel.readParcelable(D.class.getClassLoader()); // can I check here id this class is null or not found? Can I do additional coding here?
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public D getD() {
        return d;
    }

    public void setD(D d) {
        this.d = d;
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeString(details);
        parcel.writeParcelable(d, i);
    }
}

Это класс D

import android.os.Parcel;
import android.os.Parcelable;

public class D implements Parcelable {

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

        @Override
        public D createFromParcel(Parcel source) {
            return new D(source);
        }

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

    private String name;


    private D(Parcel parcel) {
        this.name = parcel.readString();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
    }
}

Iотправляю объект из деятельности в службу с помощью намерения.как мудрый

Intent intent = new Intent(MyActivity.this, MyService.class);
intent.putExtra("A_Object", a); // where a is reference of class A;
startService(intent);

При получении объекта A из MyActivity в MyService я использовал следующий код:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
  A a = intent.getParcelableExtra("A_Object");    
}

При получении этого объекта A возникла ошибка после ошибки:

  E/Parcel: Class not found when unmarshalling: 
        java.lang.ClassNotFoundException: Invalid name: 
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:400)
            at android.os.Parcel.readParcelableCreator(Parcel.java:2507)
            at android.os.Parcel.readParcelable(Parcel.java:2461)
            at com.example.D.<init>(C.java:lineNumber)

Я искал около Class not found when unmarshalling, но во всех сценариях я сделал как в решении, и это правильно.Также это происходит только с классом D, выше классов не имеют этой проблемы.

Я не могу определить, почему это происходит?Это связано с использованием памяти мобильного устройства или приложения?

Если это связано с нулевым выделением памяти, могу ли я проверить, является ли значение пустым или нет в конструкторе Parcelable, как в конструкторе C(Parcel).Пожалуйста, проверьте комментарий в этом разделе?Это хороший вариант?

В некоторых вопросах, которые я читал, это происходит на некоторых мобильных устройствах.Так что, если это связано с этим, то как я могу преодолеть эту проблему?

Также, если это не из-за мобильных устройств, то какую ошибку я совершаю при разработке структуры кода или при отправке данных.

Пожалуйста, дайте мне правильную обратную связь и решение моего вопроса Я застрял эту проблему с последних двух дней.

...