Урок 69. Передаем Parcelable объекты с помощью Intent

Обсуждение уроков
Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение damager82 » 11 апр 2012, 23:00

В этом уроке:

- добавляем объекту поддержку Parcelable
- передаем с помощью Intent

[url=http://www.startandroid.ru/ru/uroki/vse ... l:21yetxcg]Click here to read this article![/url:21yetxcg]
Последний раз редактировалось damager82 12 май 2017, 12:06, всего редактировалось 6 раз.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Gorets
Сообщения: 8
Зарегистрирован: 12 янв 2012, 12:38

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение Gorets » 12 апр 2012, 11:15

Спасибо, неплохие уроки. Внесу от себя поправку, у меня была задача передавать объекты между активити, так вот сначала я наткнулся на этот Parcelable и немного на нем подвис, так как его применения показалось мне сложным, потому я начал юзать старый, добрый, джавовский сериалайзбл, который работает лучше и проще (имхо). Ну и одно замечание к статье - зачем писать, что какой-то метод для тебя остался загадкой?, если можно его проверить в документации
Про метод describeContents ничего сказать не могу. Я не понял, зачем он нужен.
abstract int describeContents()
Describe the kinds of special objects contained in this Parcelable's marshalled representation.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение damager82 » 12 апр 2012, 11:33

Gorets писал(а):зачем писать, что какой-то метод для тебя остался загадкой?, если можно его проверить в документации
А потом меня кто-нить попросит объяснить подробней и мне нечего будет сказать. Мне это описание ни о чем не сказало. Я не понял как и для каких целей я могу использовать этот метод.

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

Gorets
Сообщения: 8
Зарегистрирован: 12 янв 2012, 12:38

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение Gorets » 12 апр 2012, 13:08

Я не правильно выразился, т.е. я хотел сказать, что "неплохо то что ты так это описываешь", а плохо, то что такие фразы могут подтолкнуть новичков на мысли типа, если тут в тутореале говорят, что не знают, значит про это вообще негде не сказано...
Как я понял его назначение. Метод предназначен для описания специальных случаев сериализации\десериализации объекта, например, его стоит переопределять в объектах наследниках, что бы метод Parcelable.Creator<MyParent> CREATOR знал какой объект возвращать. =) наверно, слабоватый с меня объяснитель получился в этом вопросе =). Ну относительного примера в статье.

public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
// распаковываем объект из Parcel

public MyParent createFromParcel(Parcel in)
{
Log.d(LOG_TAG, "createFromParcel");
int description=in.readInt(); // получаем description
Serializable s=in.readSerializable(); // считываем собственно наш объект
switch(description)
{ // приводим к нужному типу или кастомизируем как хочется и возвращаем готовый объект
case 1:
return (MyObjectChild1)s;
case 2:
return (MyObjectChild2)s;
default:
return (MyObject)s;
}

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение KamiSempai » 12 апр 2012, 13:57

Я натыкался на этот ответ. Вы забыли упомянуть, в примере, про то, какую роль здесь играет describeContents().

Код: Выделить всё

//need to be overwritten in child classes 
//MyChild_1 - return 1 and MyChild_2 - return 2
public int describeContents() {return 0;}

public void writeToParcel(Parcel out, int flags)
{
    out.writeInt(this.describeContents());
    out.writeSerializable(this);
}
Честно говоря, это как-то... не элегантно. С тем же успехом можно было использовать константу. В комментариях к ответу, кстати, про это говорится. Там-же есть ссылка на, якобы, "правильный" ответ (ПРАВИЛЬНЫЙ ОТВЕТ).
Я с английским не очень дружу, поэтому так и не смог понять зачем это все-таки нужно.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение damager82 » 12 апр 2012, 14:23

KamiSempai писал(а):не смог понять зачем это все-таки нужно.
Я тоже видел эту ссылку. Там написано, что флаг CONTENTS_FILE_DESCRIPTOR используется в методе describeContents при передаче через Parcel объекта FileDescriptor.
Возможно внутри Parcel-а читается этот describeContents и от этого зависит, как будет храниться объект.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение KamiSempai » 12 апр 2012, 15:01

Значит я понял правильно. Только все равно ни чего не понятно :)
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Gorets
Сообщения: 8
Зарегистрирован: 12 янв 2012, 12:38

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение Gorets » 12 апр 2012, 16:44

остановимся на выводе
"This whole Parceable functionality looks unfinished (read: has bad design)." =)))

irukanji
Сообщения: 12
Зарегистрирован: 26 мар 2012, 12:51

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение irukanji » 26 май 2012, 13:07

странно но у меня форсклоз после лога writeToParcel ... хотя все сопипастил точно...

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение damager82 » 28 май 2012, 09:38

irukanji писал(а):странно но у меня форсклоз после лога writeToParcel ... хотя все сопипастил точно...
А что говорит в логах и на какую строку ругается?
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

irukanji
Сообщения: 12
Зарегистрирован: 26 мар 2012, 12:51

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение irukanji » 28 май 2012, 18:15

я наверное забыл в манифест прописать активити

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение Prospekt » 30 май 2012, 23:36

Второй метод, по моему предположению, нужен для работы с массивами. Ведь парсить можно не только сам объект, но и массив таких объектов. Если бы я был парсером, то при восстановлении массива объектами мне нужно было:
1) создать сам массив объектов
2) заполнить этот массив значениями

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

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение Prospekt » 31 май 2012, 08:38

Спасибо за хорошие уроки. Смотрел много книг и блогов по разработке под Андрюше, но как-то желаемого не получил. А тут все понятно, достаточно добродно.

Я считаю, что слова
Про метод describeContents ничего сказать не могу. Я не понял, зачем он нужен.
должны быть. Конструкция действительно не однозначная, и когда человек видит эти слова, он понимает, что он все понял правильно. Во всяком случае читатель не будет чувствовать себя дураком из-за того, что не понял то, что ему собственно нормально не объяснили.
Так что не слушайте Горца.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение damager82 » 31 май 2012, 16:44

Prospekt писал(а):Второй метод, по моему предположению, нужен для работы с массивами.
Я поначалу тоже так подумал, но сделал пример и у меня чет не сложилось. Будет время - покопаюсь подробнее.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение Prospekt » 11 июн 2012, 13:50

Второй метод, по моему предположению, нужен для работы с массивами. Ведь парсить можно не только сам объект, но и массив таких объектов. Если бы я был парсером, то при восстановлении массива объектами мне нужно было:
1) создать сам массив объектов
2) заполнить этот массив значениями

Так вот, для того, чтобы выполнить пункт первый и нужен второй метод. Почему этот участок кода нельзя было автоматизировать я не знаю, возможно есть какое-то ограничение самого языка, и даный метод нужен, чтобы не ломать конструкции этого языка.
Как это обычно и бывает, я оказался прав. Все дело в том,, что парсеру при сборе объекта нужно вернуть массив некоторого типа (если конечны сам объект содержит массивы), поэтому это массив нужно создать.

Есть такое ограничение языка java, как невозможность создавать экземпляры и массивы экземпляров параметрических классов. Т.е. вот так сделать нельзя:

Код: Выделить всё

class Creator<T>{
    public T item;
    public T[] data;

    public Creator() {
        item = new T();
        data = new T[5];
    }
}
То, что у класса T может и не быть пустого конструктора - это понятно. Но вот то, что нельзя создавать массивы параметрического класса - это для меня в некотором смысле новость.

Отсюда очевидно, что второй метод - это не прихоть разработчиков, это как говорится осознанная необходимость. У Parcelable просто нет других вариантов, поэтому создавать объекты и массивы поручили нам. А то, что сам Parcelable вынужден работать с классом-параметров наверное объяснять не надо.

PS: Приятно сделать интуитивное предположение, а потом его же и подтвердить. Придется себя похвалить. :)

dim_
Сообщения: 11
Зарегистрирован: 12 авг 2012, 22:13

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение dim_ » 28 окт 2012, 14:34

Добрый день, подскажите, а как передать к примеру коллекцию объектов? Спасибо.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение rezak90 » 28 окт 2012, 14:49

dim_ писал(а):Добрый день, подскажите, а как передать к примеру коллекцию объектов? Спасибо.
смотря каких объектов, если int или String то у Intent есть два метода putIntegerArrayListExtra, putStringArrayListExtra.
Если же своих объектов, то: putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value)
Так же есть альтернативные велосипеды:
1) Делаем класс контейнер-упаковщик, в котором храним наш ArrayList;
2) Создаём класс который extends ArrayList implements Parcelable и упаковываем его;
R.id.team
Политика на форуме запрещена

Аватара пользователя
Iron Acorn
Сообщения: 10
Зарегистрирован: 29 окт 2012, 16:45

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение Iron Acorn » 18 янв 2013, 16:31

Мне нужно передать Список своих объектов.
Для этого, собственно, создал класс:

Код: Выделить всё

public class  music implements Parcelable{
	private String name;
	private String link;
	private boolean box;
	music(String _name,String _link,boolean _box) {
		name =_name;
		link = _link;
		box = _box;
	}
	public  String getName() {
		return name;
	}
	public String getLink() {
		return link;
	}
	public boolean getBox() {
		return box;
	}
	public void setBox(boolean bx)
	{
		box = bx;
	}
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}
	public void writeToParcel(Parcel dest, int flags) {
		// TODO Auto-generated method stub
		
	}

}
Передаю вот так:

Код: Выделить всё

        Intent intentMusic = new Intent(this,MusicPlayer.class);
    	intentMusic.putParcelableArrayListExtra("list",musics);
    	startActivity(intentMusic);
Принимаю:

Код: Выделить всё

        Intent intent = getIntent();
        musics = intent.getParcelableArrayListExtra("list");
Проследил в логах, что на этом месте:
musics = intent.getParcelableArrayListExtra("list");
Приложение вылетает. Что я не так делаю?

Аватара пользователя
DOS
Сообщения: 7
Зарегистрирован: 04 фев 2013, 16:51

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение DOS » 04 фев 2013, 17:00

Подскажите пожалуйста, можно ли этим методом передать BluetoothSocket?

при попытке записать в парсел сокет, приложение валится с ошибкой

protected BluetoothSocket fSocket;
......
// упаковываем объект в Parcel
public void writeToParcel(Parcel parcel, int flags) {
Log.d(LOG_TAG, "writeToParcel");
parcel.writeValue(fSocket);
}

java.lang.RuntimeException: Parcel: unable to marshal value android.bluetooth.BluetoothSocket@41246d38

Эти товарищи пишут, что всё плохо (
http://stackoverflow.com/questions/7894 ... ther-using

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 69. Передаем Parcelable объекты с помощью Intent

Сообщение rezak90 » 04 фев 2013, 19:26

потому что BluetoothSocket не парселейбл
R.id.team
Политика на форуме запрещена

Ответить