Staram się, aby moje przedmioty można było nadawać na działce. Mam jednak obiekty niestandardowe, które mają ArrayList
atrybuty innych obiektów niestandardowych, które utworzyłem.
Jaki byłby najlepszy sposób to zrobić?
Staram się, aby moje przedmioty można było nadawać na działce. Mam jednak obiekty niestandardowe, które mają ArrayList
atrybuty innych obiektów niestandardowych, które utworzyłem.
Jaki byłby najlepszy sposób to zrobić?
Odpowiedzi:
Przykłady tego można znaleźć tutaj , tutaj (kod jest pobierany tutaj) i tutaj .
Możesz do tego utworzyć klasę POJO, ale musisz dodać dodatkowy kod, aby to zrobić Parcelable
. Zobacz implementację.
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];
}
};
}
Po utworzeniu tej klasy możesz łatwo przepuścić obiekty tej klasy przez Intent
podobne i odzyskać ten obiekt w działaniu docelowym.
intent.putExtra("student", new Student("1","Mike","6"));
Tutaj uczeń jest kluczem, którego potrzebujesz, aby rozpakować dane z pakietu.
Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");
Ten przykład pokazuje tylko String
typy. Możesz jednak spakować dowolne dane. Wypróbuj to.
EDYCJA: Kolejny przykład , sugerowany przez Rukmal Dias .
writeToParcel
metody ma znaczenie?
Oto strona internetowa, na której można utworzyć klasę działkową z utworzonej przez siebie klasy:
IntelliJ IDEA i Android Studio mają wtyczki do tego:
Wtyczki te generują kod paczkowany Androida na podstawie pól w klasie.
Android Parcelable code generator
public class Sample {
int id;
String name;
}
File > Settings... > Plugins
i kliknij Browse repositories...
przycisk.
Po prostu adnotujesz POJO specjalną adnotacją, a biblioteka zajmie się resztą.
Ostrzeżenie!
Nie jestem pewien, czy Hrisey, Lombok i inne biblioteki do generowania kodu są kompatybilne z nowym systemem kompilacji Androida. Mogą lub nie mogą ładnie grać z kodem wymiany na gorąco (np. JRebel, Instant Run).
Plusy:
Cons:
Ostrzeżenie!
Hrisey ma znany problem z Javą 8 i dlatego nie można go obecnie używać do programowania Androida. Zobacz nr 1 Nie można znaleźć błędów symboli (JDK 8) .
Hrisey opiera się na Lombok . Klasa działki przy użyciu Hrisey :
@hrisey.Parcelable
public final class POJOClass implements android.os.Parcelable {
/* Fields, accessors, default constructor */
}
Teraz nie musisz wdrażać żadnych metod interfejsu Parcelable. Hrisey wygeneruje cały wymagany kod podczas fazy wstępnego przetwarzania.
Hrisey w zależnościach Gradle:
provided "pl.mg6.hrisey:hrisey:${hrisey.version}"
Zobacz tutaj obsługiwane typy. ArrayList
Jest wśród nich.
Zainstaluj wtyczkę - Hrisey xor Lombok * - dla swojego IDE i zacznij korzystać z jej niesamowitych funkcji!
* Nie włączaj wtyczek Hrisey i Lombok razem, bo pojawi się błąd podczas uruchamiania IDE.
Klasa paczki za pomocą Parceler :
@java.org.parceler.Parcel
public class POJOClass {
/* Fields, accessors, default constructor */
}
Aby użyć wygenerowanego kodu, możesz odwoływać się do wygenerowanej klasy bezpośrednio lub za pomocą Parcels
klasy narzędzi, używając
public static <T> Parcelable wrap(T input);
Aby wyłuskać @Parcel
, po prostu wywołaj następującą metodę Parcels
klasy
public static <T> T unwrap(Parcelable input);
Działka w zależnościach Gradle:
compile "org.parceler:parceler-api:${parceler.version}"
provided "org.parceler:parceler:${parceler.version}"
Poszukaj w README obsługiwanych typów atrybutów .
AutoParcel to AutoValue rozszerzenie które umożliwia generowanie wartości Parcelable.
Po prostu dodaj implements Parcelable
do swoich @AutoValue
modeli z adnotacjami:
@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 w pliku kompilacji 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 to procesor adnotacji, który automatycznie generuje bezpieczny kod paczkowany dla Kotlin i Java. PaperParcel obsługuje Klasy danych Kotlin, AutoValue Google'a poprzez rozszerzenie AutoValue lub zwykłe obiekty Java Bean.
Przykład użycia z dokumentów .
Dodaj adnotację do swojej klasy danych @PaperParcel
, zaimplementuj PaperParcelable
i dodaj instancję statyczną JVM, PaperParcelable.Creator
np .:
@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;
}
}
Dla użytkowników Kotlin, patrz Wykorzystanie Kotlin ; Dla użytkowników AutoValue, zobacz Korzystanie z AutoValue .
ParcelableGenerator (README jest napisane po chińsku i nie rozumiem tego. Mile widziane są wkłady w tę odpowiedź od twórców anglojęzycznych)
Przykład użycia z 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;
}
}
W android-apt asysty plugin w pracy z procesorami adnotacji w połączeniu z systemem Android Studio.
To bardzo proste, możesz użyć wtyczki na Android Studio, aby tworzyć obiekty Paczkowate.
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];
}
};}
Teraz możesz użyć biblioteki Parceler do konwersji dowolnej niestandardowej klasy na paczkową. Dodaj adnotację do swojej klasy POJO za pomocą @Parcel . na przykład
@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; }
}
możesz utworzyć obiekt klasy Przykład i owinąć Paczki i wysłać jako pakiet przez zamiar. na przykład
Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));
Teraz, aby uzyskać obiekt klasy niestandardowej, wystarczy użyć
Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
Paczka z Androidem ma kilka unikalnych cech. Poniżej podano:
Przykład: aby stworzyć klasę Parceble, należy zaimplementować Parceble. Percable ma 2 metody:
int describeContents();
void writeToParcel(Parcel var1, int var2);
Załóżmy, że masz klasę Person, która ma 3 pola: FirstName, LastName i wiek. Po wdrożeniu interfejsu Parceble. ten interfejs podano poniżej:
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);
}
}
W tej writeToParcel
metodzie piszemy / dodajemy dane na Paczce w zamówieniu. Następnie musimy dodać poniższy kod do odczytu danych z paczki:
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];
}
};
Tutaj klasa Person bierze paczkę i pobiera dane w tej samej kolejności podczas pisania.
Teraz podczas intencji getExtra
iputExtra
kodu podano poniżej:
Dodaj dodatkowe :
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);
Uzyskaj dodatkowe:
Person person=getIntent().getParcelableExtra("person");
Klasa Full Person znajduje się poniżej :
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 :)
Utwórz klasę działki bez wtyczki w Android Studio
implementuje Parcelable w twojej klasie, a następnie umieść kursor na „implements Parcelable” i naciśnij Alt+Enter
i wybierz Add Parcelable implementation
(patrz zdjęcie). Otóż to.
Położyć:
bundle.putSerializable("key",(Serializable) object);
Aby uzyskać:
List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));
ClassCastException
jeśli obiekt nie zaimplementuje Serializable
.