本文继续对 AutoValue 的使用方法进行深入介绍。
前置文章:AutoValue 探究(一)
默认情况下,AutoValue 生成的类中域是非空的,如果要使得域可以为空,则需要使用 @Nullable
注解,如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| import android.support.annotation.Nullable;
import com.google.auto.value.AutoValue;
import com.google.gson.annotations.SerializedName;
@AutoValue
public abstract class User {
@SerializedName("id")
public abstract int id();
@Nullable
@SerializedName("name")
public abstract String name();
}
|
生成的代码为:
1
2
3
4
5
6
7
8
9
10
11
12
| final class AutoValue_User extends User {
private final int id;
private final String name;
AutoValue_User(
int id,
@Nullable String name) {
this.id = id;
this.name = name;
}
}
|
AutoValue 与 Gson 搭配使用时,要额外做一些处理工作。
首先,需要引入 AutoValue Gson 插件,即在 Gradle 文件中加入如下依赖描述:
1
2
| annotationProcessor 'com.ryanharter.auto.value:auto-value-gson:0.5.0'
provided 'com.ryanharter.auto.value:auto-value-gson:0.5.0'
|
其次,申明的抽象类中,每个方法上面添加对应的注解,然后再添加一个 typeAdapter
方法,申明这个方法,Gson 就会根据这个找到对应的 adapter,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| @AutoValue
public abstract class User {
@SerializedName("id")
public abstract int id();
@SerializedName("name")
public abstract String name();
public static User newInstance(int id, String name) {
return new AutoValue_User(id, name);
}
public static TypeAdapter<User> typeAdapter(Gson gson) {
return new AutoValue_User.GsonTypeAdapter(gson);
}
}
|
再次,声明一个 TypeAdapterFactory
的实现类,这个类应是抽象类,AutoValue 也会自动生成其实现类,比如:
1
2
3
4
5
6
7
| @GsonTypeAdapterFactory
public abstract class MyAdapterFactory implements TypeAdapterFactory {
public static TypeAdapterFactory create() {
return new AutoValueGson_MyAdapterFactory();
}
}
|
最后,在 json 字符串转值类的时候,需要自用到上面所申明的 MyAdapterFactory
,比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| @Test
public void testUserToJson() {
User user = User.newInstance(100, "test");
String json = new Gson().toJson(user);
System.out.println(json);
Assert.assertEquals("{\"id\":100,\"name\":\"test\"}", json);
}
@Test
public void testUserParseFromJson() {
String json = "{\"id\":100,\"name\":\"test\"}";
// 自定义的Gson对象,需要配置 MyAdapterFactory
Gson gson = new GsonBuilder().registerTypeAdapterFactory(MyAdapterFactory.create()).create();
User user = gson.fromJson(json, User.class);
System.out.println(user);
Assert.assertNotNull(user);
Assert.assertEquals(user.name(), "test");
Assert.assertEquals(user.id(), 100);
NullableUser nullableUser = gson.fromJson(json, NullableUser.class);
System.out.println(nullableUser);
Assert.assertNotNull(nullableUser);
Assert.assertEquals(nullableUser.name(), "test");
Assert.assertEquals(nullableUser.id(), 100);
}
|
Serializable 是 Java 自带的序列化方式,和 AutoValue 结合不影响原先使用,只需要在申明的 Model 中实现 Serializable 接口即可。
Parcelable 是 Android 提供的序列化方式,如果需要和 AutoValue 结合使用,和 Serializable 基本差不多,实现相关接口,添加相关插件 AutoValue Parcel 即可:
1
2
3
4
| annotationProcessor 'com.ryanharter.auto.value:auto-value-parcel:0.2.5'
// Optionally for TypeAdapter support
compile 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.5'
|
结果自动生成的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| final class AutoValue_User extends $AutoValue_User {
public static final Parcelable.Creator<AutoValue_User> CREATOR = new Parcelable.Creator<AutoValue_User>() {
@Override
public AutoValue_User createFromParcel(Parcel in) {
return new AutoValue_User(
in.readInt(),
in.readString()
);
}
@Override
public AutoValue_User[] newArray(int size) {
return new AutoValue_User[size];
}
};
AutoValue_User(int id, String name) {
super(id, name);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id());
dest.writeString(name());
}
@Override
public int describeContents() {
return 0;
}
}
|
Android Model正确使用姿势 —— AutoValue