Страница 1 из 3

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

Добавлено: 11 апр 2012, 23:00
damager82
В этом уроке:

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

[url=http://www.startandroid.ru/ru/uroki/vse ... l:21yetxcg]Click here to read this article![/url:21yetxcg]

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

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

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

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

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

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

Добавлено: 12 апр 2012, 13:08
Gorets
Я не правильно выразился, т.е. я хотел сказать, что "неплохо то что ты так это описываешь", а плохо, то что такие фразы могут подтолкнуть новичков на мысли типа, если тут в тутореале говорят, что не знают, значит про это вообще негде не сказано...
Как я понял его назначение. Метод предназначен для описания специальных случаев сериализации\десериализации объекта, например, его стоит переопределять в объектах наследниках, что бы метод 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;
}

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

Добавлено: 12 апр 2012, 13:57
KamiSempai
Я натыкался на этот ответ. Вы забыли упомянуть, в примере, про то, какую роль здесь играет 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);
}
Честно говоря, это как-то... не элегантно. С тем же успехом можно было использовать константу. В комментариях к ответу, кстати, про это говорится. Там-же есть ссылка на, якобы, "правильный" ответ (ПРАВИЛЬНЫЙ ОТВЕТ).
Я с английским не очень дружу, поэтому так и не смог понять зачем это все-таки нужно.

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

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

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

Добавлено: 12 апр 2012, 15:01
KamiSempai
Значит я понял правильно. Только все равно ни чего не понятно :)

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

Добавлено: 12 апр 2012, 16:44
Gorets
остановимся на выводе
"This whole Parceable functionality looks unfinished (read: has bad design)." =)))

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

Добавлено: 26 май 2012, 13:07
irukanji
странно но у меня форсклоз после лога writeToParcel ... хотя все сопипастил точно...

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

Добавлено: 28 май 2012, 09:38
damager82
irukanji писал(а):странно но у меня форсклоз после лога writeToParcel ... хотя все сопипастил точно...
А что говорит в логах и на какую строку ругается?

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

Добавлено: 28 май 2012, 18:15
irukanji
я наверное забыл в манифест прописать активити

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

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

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

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

Добавлено: 31 май 2012, 08:38
Prospekt
Спасибо за хорошие уроки. Смотрел много книг и блогов по разработке под Андрюше, но как-то желаемого не получил. А тут все понятно, достаточно добродно.

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

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

Добавлено: 31 май 2012, 16:44
damager82
Prospekt писал(а):Второй метод, по моему предположению, нужен для работы с массивами.
Я поначалу тоже так подумал, но сделал пример и у меня чет не сложилось. Будет время - покопаюсь подробнее.

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

Добавлено: 11 июн 2012, 13:50
Prospekt
Второй метод, по моему предположению, нужен для работы с массивами. Ведь парсить можно не только сам объект, но и массив таких объектов. Если бы я был парсером, то при восстановлении массива объектами мне нужно было:
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: Приятно сделать интуитивное предположение, а потом его же и подтвердить. Придется себя похвалить. :)

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

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

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

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

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

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

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

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");
Приложение вылетает. Что я не так делаю?

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

Добавлено: 04 фев 2013, 17:00
DOS
Подскажите пожалуйста, можно ли этим методом передать 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

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

Добавлено: 04 фев 2013, 19:26
rezak90
потому что BluetoothSocket не парселейбл