Объекты таким способом передавать можно, но они должны реализовывать интерфейс Serializable или Parcelable. Первый вариант по некоторым найденным мной отзывам, снижает производительность приложения. Второй - давайте рассмотрим внимательнее.
Вот пример класса одного из моих приложений:
Как видим,он реализует интерфейс Parcelable, а значит может легко передаваться между Activity. Как мы этого добиваемся? Мы дополняем логику класса методами для его Parcel-изации и Де-parcel-изации, проще говоря, сохранения в Parcel и восстановления из него. Parcel тут можно рассматривать как некий буфер, в который можно сложить в определённом порядке данные любых типов и затем (в том же порядке !) их оттуда извлечь.
- public class Email implements Parcelable {
- private String address;
- private String type;
- private Email(Parcel in) {
- this.address = in.readString();
- this.type = in.readString();
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- public String getType() {
- return type;
- }
- public void setType(String t) {
- this.type = t;
- }
- public Email(String a, String t) {
- this.address = a;
- this.type = t;
- }
- public int describeContents() {
- return 0;
- }
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public Email createFromParcel(Parcel in) {
- return new Email(in);
- }
- public Email[] newArray(int size) {
- return new Email[size];
- }
- };
- public void writeToParcel(Parcel parcel, int i) {
- parcel.writeString(address);
- parcel.writeString(type);
- }
- }
Складывать содержимое полей класса в Parcel очень просто. Это реализуется в методе writeToParcel. Для восстановления объекта действуем так: Создаём вложенный класс Parcelable.Creator, в котором реализуем два метода. Второй выглядит всегда одинаково, а вот первый для нас весьма важен: он вызовет новый конструктор нашего класса, передавая в него Parcel. В конструкторе мы должны реализовать логику, обратную методу writeToParcel, т.е. вычитать из Parcel-а значения полей класса в том же порядке, в каком их туда записывали. В случае простых полей типа String это несложно. Если же у нас есть поля типа ArrayList, то делаем так:
p.writeInt(phone.size());
for (int i = 0; i < phone.size(); i++) {
p.writeString(phone.get(i));
}
для сохранения, и
int count = p.readInt();
for (int i = 0; i < count; i++) {
String ph = p.readString();
phone.add(ph);
}
для восстановления. Тут p, как вы, наверное, догадались - объект класса Parcel, а phone - поле типа ArrayList.Если полями нашего класса являются другие наши классы, то мы должны их также "научить Parcel-изоваться". Тогда поля таких типов мы будем укладывать в Parcel методом
p.writeParcelable(organization, Parcelable.CONTENTS_FILE_DESCRIPTOR);
и извлекать оттуда методом
organization = p.readParcelable(getClass().getClassLoader());
Спасибо, очень полезно оказалось.
ОтветитьУдалитьА где тип для Parcelable.Creator?
ОтветитьУдалитьСтоит делать так:
Parcelable.Creator CREATOR = new Parcelable.Creator()
Блин, теги съелись. Повторю:
ОтветитьУдалитьParcelable.Creator[Email] CREATOR = new Parcelable.Creator[Email]()...
квадратные скобки заменить угловыми.
Круто, давно искал что-то подобное, только не понятно, что в себе содержит переменная organization
ОтветитьУдалитьА не желаете написать статью про то, как сохранить произвольно добавленные визуальные компоненты на экране после поворота экрана(screen rotation)? Думаю данная статья будет актуальна.
ОтветитьУдалитьпрошу прощения, но не понял как потом этот класс в дугой активити получить?
ОтветитьУдалитьа что если в моем объекте хранится ArrayList. Как реализовать метод writeToParcel?
ОтветитьУдалитьсамое простое это intent
ОтветитьУдалить