Tôi đang cố gắng để làm cho các đối tượng của tôi Parcelable. Tuy nhiên, tôi có các đối tượng tùy chỉnh và các đối tượng đó có ArrayList
thuộc tính của các đối tượng tùy chỉnh khác mà tôi đã thực hiện.
cách nào tốt nhất để làm việc này?
Tôi đang cố gắng để làm cho các đối tượng của tôi Parcelable. Tuy nhiên, tôi có các đối tượng tùy chỉnh và các đối tượng đó có ArrayList
thuộc tính của các đối tượng tùy chỉnh khác mà tôi đã thực hiện.
cách nào tốt nhất để làm việc này?
Câu trả lời:
Bạn có thể tìm thấy một số ví dụ về điều này ở đây , ở đây (mã được lấy ở đây) và ở đây .
Bạn có thể tạo một lớp POJO cho việc này, nhưng bạn cần thêm một số mã bổ sung để tạo nó Parcelable
. Có một cái nhìn vào việc thực hiện.
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];
}
};
}
Khi bạn đã tạo lớp này, bạn có thể dễ dàng chuyển các đối tượng của lớp này thông qua Intent
như thế này và khôi phục đối tượng này trong hoạt động đích.
intent.putExtra("student", new Student("1","Mike","6"));
Ở đây, sinh viên là chìa khóa mà bạn sẽ yêu cầu hủy dữ liệu từ gói.
Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");
Ví dụ này chỉ hiển thị String
các loại. Nhưng, bạn có thể gửi bất kỳ loại dữ liệu nào bạn muốn. Hãy thử nó.
EDIT: Một ví dụ khác , được đề xuất bởi Rukmal Dias .
writeToParcel
phương thức có quan trọng không?
Đây là một trang web để tạo một Parcelable Class từ lớp bạn đã tạo:
IntelliJ IDEA và Android Studio có plugin cho việc này:
Các plugin này tạo mã soạn sẵn Android Parcelable dựa trên các trường trong lớp.
Android Parcelable code generator
public class Sample {
int id;
String name;
}
File > Settings... > Plugins
và nhấp vào Browse repositories...
nút.
Bạn chỉ cần chú thích một POJO với một chú thích đặc biệt và thư viện sẽ làm phần còn lại.
Cảnh báo!
Tôi không chắc chắn rằng Hrisey, Lombok và các thư viện tạo mã khác tương thích với hệ thống xây dựng mới của Android. Họ có thể hoặc không thể chơi độc đáo với mã hoán đổi nóng (ví dụ jRebel, Instant Run).
Ưu điểm:
Nhược điểm:
Cảnh báo!
Hrisey có một vấn đề đã biết với Java 8 và do đó không thể được sử dụng để phát triển Android hiện nay. Xem # 1 Không thể tìm thấy lỗi biểu tượng (JDK 8) .
Hrisey dựa trên Lombok . Lớp Parcelable sử dụng Hrisey :
@hrisey.Parcelable
public final class POJOClass implements android.os.Parcelable {
/* Fields, accessors, default constructor */
}
Bây giờ bạn không cần phải thực hiện bất kỳ phương pháp nào của giao diện Parcelable. Hrisey sẽ tạo ra tất cả các mã cần thiết trong giai đoạn tiền xử lý.
Hrisey trong phụ thuộc Gradle:
provided "pl.mg6.hrisey:hrisey:${hrisey.version}"
Xem ở đây để biết các loại được hỗ trợ. Đây ArrayList
là một trong số họ.
Cài đặt plugin - Hrisey xor Lombok * - cho IDE của bạn và bắt đầu sử dụng các tính năng tuyệt vời của nó!
* Không bật các plugin Hrisey và Lombok với nhau hoặc bạn sẽ gặp lỗi trong khi khởi chạy IDE.
Lớp Parcelable sử dụng Parceler :
@java.org.parceler.Parcel
public class POJOClass {
/* Fields, accessors, default constructor */
}
Để sử dụng mã được tạo, bạn có thể tham chiếu trực tiếp lớp được tạo hoặc thông qua Parcels
lớp tiện ích bằng cách sử dụng
public static <T> Parcelable wrap(T input);
Để hủy đăng ký @Parcel
, chỉ cần gọi phương thức sau của Parcels
lớp
public static <T> T unwrap(Parcelable input);
Parceler trong phụ thuộc Gradle:
compile "org.parceler:parceler-api:${parceler.version}"
provided "org.parceler:parceler:${parceler.version}"
Xem trong README cho các loại thuộc tính được hỗ trợ .
AutoParcel là tiện ích mở rộng AutoValue cho phép tạo giá trị Parcelable.
Chỉ cần thêm implements Parcelable
vào các @AutoValue
mô hình chú thích của bạn :
@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 trong tập tin xây dựng 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 là một bộ xử lý chú thích tự động tạo mã soạn sẵn Parcelable an toàn loại cho Kotlin và Java. PaperParcel hỗ trợ các lớp dữ liệu Kotlin, AutoValue của Google thông qua tiện ích mở rộng AutoValue hoặc chỉ các đối tượng bean Java thông thường.
Ví dụ sử dụng từ tài liệu .
Chú thích lớp dữ liệu của bạn với @PaperParcel
, thực hiện PaperParcelable
và thêm một cá thể tĩnh JVM, ví PaperParcelable.Creator
dụ:
@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;
}
}
Đối với người dùng Kotlin, xem Sử dụng Kotlin ; Đối với người dùng AutoValue, xem Sử dụng AutoValue .
ParcelableGenerator (README được viết bằng tiếng Trung Quốc và tôi không hiểu điều đó. Đóng góp cho câu trả lời này từ các nhà phát triển nói tiếng Anh-Trung Quốc được chào đón)
Ví dụ sử dụng từ 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;
}
}
Các android-apt hỗ trợ plugin trong làm việc với bộ vi xử lý chú thích trong sự kết hợp với Android Studio.
Nó rất dễ dàng, bạn có thể sử dụng một plugin trên android studio để tạo các đối tượng 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];
}
};}
Bây giờ bạn có thể sử dụng thư viện Parceler để chuyển đổi bất kỳ lớp tùy chỉnh nào của bạn theo dạng bưu kiện. Chỉ cần chú thích lớp POJO của bạn với @Parcel . ví dụ
@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; }
}
bạn có thể tạo một đối tượng của lớp Ví dụ và bọc qua các Bưu phẩm và gửi dưới dạng một gói thông qua ý định. ví dụ
Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));
Bây giờ để có được đối tượng Lớp tùy chỉnh, chỉ cần sử dụng
Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
Android parcable có một số điều độc đáo. Những người được đưa ra dưới đây:
Ví dụ: Để tạo một Parceble lớp, nó phải được thực hiện Parceble. Percable có 2 phương thức:
int describeContents();
void writeToParcel(Parcel var1, int var2);
Giả sử bạn có một lớp Người và nó có 3 trường, FirstName, LastName và age. Sau khi thực hiện giao diện Parceble. giao diện này được đưa ra dưới đây:
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);
}
}
Ở đây writeToParcel
phương pháp chúng tôi đang viết / thêm dữ liệu trên Parcel theo thứ tự. Sau này, chúng ta phải thêm mã dưới đây để đọc dữ liệu từ bưu kiện:
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];
}
};
Ở đây, lớp Person đang lấy một bưu kiện và nhận dữ liệu theo cùng một thứ tự trong khi viết.
Bây giờ trong ý định getExtra
và putExtra
mã được đưa ra dưới đây:
Đặt thêm :
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);
Nhận thêm:
Person person=getIntent().getParcelableExtra("person");
Lớp Full Person được đưa ra dưới đây:
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 :)
Tạo lớp Parcelable không có plugin trong Android Studio
thực hiện Parcelable trong lớp của bạn và sau đó đặt con trỏ vào "thực hiện Parcelable" và nhấn Alt+Enter
và chọn Add Parcelable implementation
(xem hình ảnh). đó là nó.
Để đặt:
bundle.putSerializable("key",(Serializable) object);
Để có được:
List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));
ClassCastException
nếu đối tượng không thực hiện Serializable
.