Як я можу зробити власні об'єкти парцельованими?


338

Я намагаюся зробити свої об’єкти розбірливими. Однак у мене є власні об’єкти, і ці об’єкти мають ArrayListатрибути інших створених мною об'єктів.

Який був би найкращий спосіб зробити це?

Відповіді:


431

Деякі приклади цього ви можете знайти тут , тут (код взятий тут) і тут .

Для цього можна створити клас POJO, але для його створення потрібно додати додатковий код Parcelable. Погляньте на реалізацію.

public class Student implements Parcelable{
        private String id;
        private String name;
        private String grade;

        // Constructor
        public Student(String id, String name, String grade){
            this.id = id;
            this.name = name;
            this.grade = grade;
       }
       // Getter and setter methods
       .........
       .........

       // Parcelling part
       public Student(Parcel in){
           String[] data = new String[3];

           in.readStringArray(data);
           // the order needs to be the same as in writeToParcel() method
           this.id = data[0];
           this.name = data[1];
           this.grade = data[2];
       }

       verride
       public int describeContents(){
           return 0;
       }

       @Override
       public void writeToParcel(Parcel dest, int flags) {
           dest.writeStringArray(new String[] {this.id,
                                               this.name,
                                               this.grade});
       }
       public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
           public Student createFromParcel(Parcel in) {
               return new Student(in); 
           }

           public Student[] newArray(int size) {
               return new Student[size];
           }
       };
   }

Створивши цей клас, ви можете легко передавати об'єкти цього класу через Intentподібне і відновити цей об’єкт у цільовій діяльності.

intent.putExtra("student", new Student("1","Mike","6"));

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

Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");

Цей приклад показує лише Stringтипи. Але ви можете розіслати будь-які потрібні вам дані. Спробуй.

EDIT: Ще один приклад , запропонований Рукмалом Діасом .


@Rukmal Dias 10x. Насправді я мушу відредагувати свою відповідь та додати якийсь код, оскільки ці посилання вже не будуть активними через день.
вигадка

16
ОП запитують, як передавати користувацькі об'єкти не звичайною строкою Будь-хто може пройти звичайні струни. Чи можете ви пояснити, як створити його за допомогою CUSTOM OBJECT

Чи потрібно реально реалізовувати частини кодування / декодування, якщо я надсилаю їх лише за допомогою LocalBroadcastManager? Чи достатньо реалізувати Parcelable і поставити як додатковий?
JohnyTex

Чому ви використовуєте рядковий рядок замість того, щоб просто писати рядки послідовно?
Квентін Рой

Чи має значення порядок членів під час створення масиву рядків всередині writeToParcelметоду?
Прахар Мохан Срівастава


113

IntelliJ IDEA та Android Studio мають додатки для цього:

Ці плагіни генерують код котла на платформі Android Parcelable на основі полів у класі.

Демонстрація плагінів


ТИЛИ новий спосіб робити це, приємно!
sud007

56

1. Імпорт Android Parcelable code generator

введіть тут опис зображення

2. Створіть клас

public class Sample {
    int id;
    String name;
}

3. Створити> Розділити з меню

введіть тут опис зображення введіть тут опис зображення

Зроблено.


7
Для тих, хто не знає, де знаходиться діалогове вікно Огляд сховищ: File > Settings... > Pluginsта натисніть Browse repositories...кнопку.
DaedalusAlpha

Дякую, дуже допомогли!
Страхінджа Айваз

21

Як? З анотаціями.

Ви просто коментуєте POJO спеціальною анотацією, а все інше - бібліотека.

Увага!

Я не впевнений, що бібліотеки Hrisey, Lombok та інших бібліотек генерації коду сумісні з новою системою збірки Android. Вони можуть або не можуть добре грати з гарячим кодом заміни (наприклад, jRebel, миттєвий запуск).

Плюси:

  • Бібліотеки генерації коду рятують вас від вихідного коду.
  • Анотації роблять ваш клас красивим.

Мінуси:

  • Це добре працює для простих занять. Зробити складний клас парцелябельним може бути складним.
  • Ломбок і AspectJ не грають добре разом. [детальніше]
  • Дивіться мої застереження.

Хрісей

Увага!

У Хрісі є відома проблема з Java 8, тому її не можна використовувати для розробки Android в даний час. Див. №1 Неможливо знайти помилки символів (JDK 8) .

Хрис заснований на Ломбок . Клас розбиття за допомогою Хрісі :

@hrisey.Parcelable
public final class POJOClass implements android.os.Parcelable {
    /* Fields, accessors, default constructor */
}

Тепер вам не потрібно реалізовувати жодних методів інтерфейсу Parcelable. Hrisey генерує весь необхідний код під час фази попередньої обробки.

Хріссі в залежності від Градле:

provided "pl.mg6.hrisey:hrisey:${hrisey.version}"

Дивіться тут для підтримуваних типів. ArrayListСеред них.

Встановіть плагін - Hrisey xor Lombok * - для вашої IDE та почніть використовувати його дивовижні функції!

введіть тут опис зображення
* Не вмикайте плагіни Hrisey та Lombok разом, або ви отримаєте помилку під час запуску IDE.


Парцелер

Клас парцеляції за допомогою Parceler :

@java.org.parceler.Parcel
public class POJOClass {
    /* Fields, accessors, default constructor */
}

Для використання згенерованого коду можна звернутися до генерованого класу безпосередньо або через Parcelsклас утиліти, використовуючи

public static <T> Parcelable wrap(T input);

Щоб знешкодити @Parcel, просто зателефонуйте за наступним методом Parcelsкласу

public static <T> T unwrap(Parcelable input);

Парцелер у залежності від Gradle:

compile "org.parceler:parceler-api:${parceler.version}"
provided "org.parceler:parceler:${parceler.version}"

Подивіться в README для підтримуваних типів атрибутів .


AutoParcel

AutoParcel - розширення AutoValue, яке дозволяє генерувати значення Parcelable.

Просто додайте implements Parcelableдо @AutoValueпояснених моделей:

@AutoValue
abstract class POJOClass implements Parcelable {
    /* Note that the class is abstract */
    /* Abstract fields, abstract accessors */

    static POJOClass create(/*abstract fields*/) {
        return new AutoValue_POJOClass(/*abstract fields*/);
    }
}

AutoParcel у файлі збірки Gradle:

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

repositories {
    /*...*/
    maven {url "https://clojars.org/repo/"}
}

dependencies {
    apt "frankiesardo:auto-parcel:${autoparcel.version}"
}

PaperParcel

PaperParcel - це процесор анотацій, який автоматично генерує безпечний для типу код Parcelable котло для котлін та Java. PaperParcel підтримує класи класів даних Kotlin, Google AutoValue Google через розширення AutoValue або просто звичайні об’єкти Java Bean.

Приклад використання з документів .
Анотувати свій клас даних за допомогою @PaperParcel, реалізувати PaperParcelableта додати статичний екземпляр JVM, PaperParcelable.Creatorнаприклад:

@PaperParcel
public final class Example extends PaperParcelable {
    public static final PaperParcelable.Creator<Example> CREATOR = new PaperParcelable.Creator<>(Example.class);

    private final int test;

    public Example(int test) {
        this.test = test;
    }

    public int getTest() {
        return test;
    }
}

Для користувачів Kotlin див. Використання Kotlin ; Для користувачів AutoValue див. Розділ Використання AutoValue .


ParcelableGenerator

ParcelableGenerator (README написаний китайською мовою, і я не розумію цього. Внесок у цю відповідь від розробників англійсько-китайських мов вітається)

Приклад використання від README .

import com.baoyz.pg.Parcelable;

@Parcelable
public class User {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

В Android-схильний плагін допомагає в роботі з процесорами анотацій в поєднанні з Android Studio.


7

Я знайшов найпростіший спосіб створити клас Parcelable

введіть тут опис зображення


1
він працює добре для невеликих даних, але якщо взяти складні дані, це звичайна робота
Манохар Редді

1

Це дуже просто, ви можете використовувати плагін на андроїд-студії, щоб зробити об'єкти Parcelables.

public class Persona implements Parcelable {
String nombre;
int edad;
Date fechaNacimiento;

public Persona(String nombre, int edad, Date fechaNacimiento) {
    this.nombre = nombre;
    this.edad = edad;
    this.fechaNacimiento = fechaNacimiento;
}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.nombre);
    dest.writeInt(this.edad);
    dest.writeLong(fechaNacimiento != null ? fechaNacimiento.getTime() : -1);
}

protected Persona(Parcel in) {
    this.nombre = in.readString();
    this.edad = in.readInt();
    long tmpFechaNacimiento = in.readLong();
    this.fechaNacimiento = tmpFechaNacimiento == -1 ? null : new Date(tmpFechaNacimiento);
}

public static final Parcelable.Creator<Persona> CREATOR = new Parcelable.Creator<Persona>() {
    public Persona createFromParcel(Parcel source) {
        return new Persona(source);
    }

    public Persona[] newArray(int size) {
        return new Persona[size];
    }
};}

4
Який плагін ви маєте на увазі?
naXa

0

Тепер ви можете використовувати бібліотеку Parceler для перетворення будь-якого спеціального класу в parcelable. Просто коментуйте свій клас POJO за допомогою @Parcel . напр

    @Parcel
    public class Example {
    String name;
    int id;

    public Example() {}

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getName() { return name; }

    public int getId() { return id; }
}

ви можете створити об’єкт класу Example і прогорнутись через посилки та надіслати у вигляді пакету через наміри. напр

Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));

Тепер, щоб отримати об'єкт Custom Class, просто використовуйте

Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));

0

Android parcable має деякі унікальні речі. Ці дані наведені нижче:

  1. Ви повинні читати посилку як той самий порядок, де ви ставите дані про посилку.
  2. Повідомлення буде видалено після прочитання з посилки. Тобто, якщо ви маєте 3 дані про свою посилку. Потім після прочитаного 3 рази посилка буде порожньою.

Приклад: Щоб зробити клас Parceble, він повинен реалізувати Parceble. Провідна має 2 способи:

int describeContents();
void writeToParcel(Parcel var1, int var2);

Припустимо, у вас є клас Person, і він має 3 поля, firstName, lastName та вік. Після реалізації інтерфейсу Parceble цей інтерфейс надано нижче:

import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
    private String firstName;
    private String lastName;
    private int age;

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(firstName);
        parcel.writeString(lastName);
        parcel.writeInt(age);
    }

}

Тут writeToParcelми пишемо / додаємо дані про посилку в порядку. Після цього нам слід додати наступний код для зчитування даних з посилки:

protected Person(Parcel in) {
        firstName = in.readString();
        lastName = in.readString();
        age = in.readInt();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

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

Тут клас Person приймає посилку і отримує дані в тому ж порядку під час написання.

Тепер під час наміру getExtraта putExtraкоду наведено нижче:

Додайте додатково :

Person person=new Person();
                person.setFirstName("First");
                person.setLastName("Name");
                person.setAge(30);

                Intent intent = new Intent(getApplicationContext(), SECOND_ACTIVITY.class);
                intent.putExtra()
                startActivity(intent); 

Отримайте додатково:

Person person=getIntent().getParcelableExtra("person");

Повний клас особи надається нижче :

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

public class Person implements Parcelable{
    private String firstName;
    private String lastName;
    private int age;



    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(firstName);
        parcel.writeString(lastName);
        parcel.writeInt(age);
    }

    protected Person(Parcel in) {
        firstName = in.readString();
        lastName = in.readString();
        age = in.readInt();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

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

}

Hope this will help you 
Thanks :)

0

Створення класу Parcelable без плагіна в Android Studio

реалізує Parcelable у своєму класі, а потім кладе курсор на "реалізує Parcelable" та натискає Alt+Enterта вибирає Add Parcelable implementation(див. зображення). Це воно.

введіть тут опис зображення


-3

Покласти: bundle.putSerializable("key",(Serializable) object);

Отримати: List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));


3
Це призведе до того, ClassCastExceptionякщо об'єкт не реалізується Serializable.
naXa

1
Хоча цей фрагмент коду може вирішити питання, у тому числі пояснення дійсно допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду. Будь ласка, намагайтеся не переповнювати свій код пояснювальними коментарями, це зменшує читабельність і коду, і пояснень!
Ashish Ahuja
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.