Neon là java preprocessor library. Neon sử dụng annotation để xử lí các thuộc tính của class và auto generate java class phục vụ serialize và deserialize.
You can build from source to use this library.
Một class sử dụng Neon luôn cần implements Serializable.
Annotatate class bằng @Neon và khai báo thuộc tính.
@Neon
public class Example implements Serializable {
public int example1;
public float example2;
}
Thêm 2 phương thức bắt buộc serialize và createFromSerialized theo cấu trúc như bên dưới để Serialize và Deserialize.
@Neon
public class Example implements Serializable {
//...property
@Override
public void serialize(SerializedOutput serializedOutput) {
Example__Neon.serialize(this, serializedOutput);
}
public static Serializable.Creator<Example> CREATOR = new Creator<Example>() {
@Override
public Example createFromSerialized(SerializedInput input, DebugBuilder builder) {
Example result = new Example();
Example__Neon.createFromSerialized(result, input, builder);
return result;
}
};
}
Lưu ý: Neon sẽ xử lí và tạo ra class có dạng <Class>__Neon gồm 2 phương thức:
void serialize(<Class>, SerializedInput);
void deserialize(, SerializedOutput);
Các phương thức này có thể gọi đến 2 phương thức bắt buộc của class, hoặc gọi đến 2 phương thức của các class __Zacel khác.
Kiểu dữ liệu | Ghi Chú |
---|---|
boolean | |
int | |
long | |
float | |
double | |
String | |
NeonObject | Bao gồm các class đã được annotate bằng @Neon |
Object | Một Object bất kì chưa khai báo ở trên. Tuy nhiên phải tự tạo adapter để sử dụng. Xem thêm Custom Adapter |
Ngoài kiểu Object bất kỳ ở trên, các kiểu còn lại đều có thể khai báo theo kiểu mảng [].
Không được sử dụng private cho các thuộc tính.
Có thể sử dụng từ khóa transient để bỏ qua việc serialization.
Có hỗ trợ inner static class.
Khi thêm một thuộc tính vào class, chúng ta cần đảm bảo rằng những dữ liệu từ version cũ vẫn có thể được revert. Neon hỗ trợ quản lý version để đảm bảo có thể sử dụng dữ liệu ở các version cũ hơn.
Khai báo:
@Neon(version=1, compatibleSince=1)
public class Example implements Serializable {
public int base;
@Neon.Property(sinceVersion=1)
public int additionData;
//.. methods
}
Như ví dụ trên, để khai báo version của class, ta sử dụng @Neon(version=1), để biết một property xuất hiện từ version nào, ta sử dụng @Neon.Property(sinceVersion=1).
Để ngưng hỗ trợ các version cũ, ta thêm @Neon(compatibleSince=1). Khi đó các binary có version < 1 sẽ báo lỗi nếu sử dụng.
Mặc định version = 0, sinceVersion=0. Ngoài ra, sinceVersion không được lớn hơn version.
Quan trọng: Việc quản lý version chỉ áp dụng khi thêm thuộc tính vào class. Việc xóa tên thuộc tính có thể dẫn đến những dữ liệu của version cũ hoạt động sai.
Note: Sửa tên thuộc tính không ảnh hưởng đến quá trình serialize.
Neon hỗ trợ việc serialize và deserialize một class, mà class được dc extends từ parent. Khi đó, Neon sẽ hỗ trợ serialize từ parent, và parent cũng phải là Neon Object. Có thể thiết lập như sau:
@Neon(inheritanceSupported = true)
public class NeonChild extends NeonParent implements Serializable {
public String daddyName;
//...
}
Mặc định inheritanceSupported là true.
Sử dụng class SerializableHelper để lấy dữ liệu debug.
class Example {
public void sample() {
SerializableHelper<NeonSample> helper = new SerializableHelper();
Map.Entry<NeonSample, String> result = helper.deserialize(serializedInput, NeonSample.CREATOR, true);
// Print structure of object
Log.d(TAG, result.getValue());
}
}
Sử dụng @NonNull hoặc @NotNull cho một thuộc tính không được phép null. Khi đó zarcel sẽ cho phép đọc ghi dữ liệu mà không cần kiểm tra.
Sử dụng @Deprecated thông báo về một thuộc tính không nên sử dụng nữa. Tuy nhiên, Neon vẫn sẽ đọc và ghi thuộc tính này.
Sử dụng để thay đổi giá trị của object sau khi để deserialized. Ví dụ: Thay đổi giá trị mặc định của một thuộc tính nếu như version < MIN_VERSION.
@Neon(version = 4)
@Migrator(ColorMigrator.class)
public class ZColor implements Serializable {
int color = Color.TRANSPARENT;
}
public class ColorMigrator implements NeonMigrator<ZColor> {
@Override
void migrate(ZColor object, int fromVersion, int toVersion) {
if (fromVersion <= 3) {
// Sample code
object.color = Color.TRANSPARENT;
}
}
}
Note: Neon chỉ gọi Migrator khi class này implement NeonMigrator<? extends Serializable>
Phần này sẽ hướng dẫn sử dụng một adapter tùy biến, được sử dụng để serialize và deserialize một kiểu dữ liệu tùy chỉnh, không thể sử dụng Neon Object.
Một adapter bắt buộc implements NeonAdapter. Tham số chính là class cần serialize.
public class AnimalAdapter implements NeonAdapter<NeonAnimal> {
@Override
public void serialize(@NonNull NeonAnimal object, SerializedOutput writer) {
// Do something
/*
Example:
writer.writeInt32(object.a);
*/
}
@Override
public NeonAnimal createFromSerialized(SerializedInput reader) {
// Do something
/*
Example:
return NeonAnimal.createObject(reader.readInt32());
*/
}
}
public class CarAdapter implements NeonAdapter<Car[]> {
@Override
public void serialize(@NonNull Car[] object, SerializedOutput writer) {
// Do something
}
@Override
public Car[] createFromSerialized(SerializedInput reader) {
// Do something
}
}
Để sử dụng adapter, ta thực hiện như sau:
@Neon
public class World implements Serializable {
@Neon.Custom(adapter = AnimalAdapter.class)
NeonAnimal cat;
@Neon.Custom(adapter = CarAdapter.class)
Car[] cars;
//...Methods
}
implementation 'com.zing.zalo.neon:zarcel-utils:<version>'
Adapter dùng cho Serialization kiểu java.lang.Date
Sử dụng:
@Neon
public class Human implements Serializable {
@Neon.Custom(adapter = DateNeonAdapter.class)
Date birthday;
//...Methods
}
Adapter dùng để serialize các lớp con của một lớp cha, khi những lớp con này được sử dụng 'đa hình' và được khai báo như một lớp cha.
Sau khi tạo xong, override phương thức như bên dưới:
public class VehicleAdapter extends PolymorphismNeonAdapter<NeonVehicle> {
@Override
protected void onRegisterChildClasses() {
try {
registryAdd(NeonVehicle.CAR, NeonCar.class);
registryAdd(NeonVehicle.BIKE, NeonBike.class);
} catch (NeonDuplicateException e) {
e.printStackTrace();
}
}
}
Tại phương thức onRegisterChildClasses, đăng ký toàn bộ subclass kế thừa từ parent class.
Các phương thức được hỗ trợ:
Method | Ghi Chú |
---|---|
registryAdd(int type, Class) | Thêm một class mới |
registryUpdate(int type, Class) | Cập nhật class hiện tại |
registryRemove(int type) | Xóa class khỏi danh sách |
isRegistered(int type) | Kiểm tra một class đã có trong danh sách chưa thông qua type |
public class Street implements Serializable {
// Parent: NeonVehicle
// Child: NeonBike, NeonCar
// largestVehicle is NeonBike or NeonCar.
@Neon.Custom(adapter = VehicleAdapter.class)
public NeonVehicle largestVehicle;
//...Methods
}