国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android AutoValue使用和擴展庫

2019-10-21 21:37:34
字體:
來源:轉載
供稿:網(wǎng)友

一、什么是AutoValue

意思就是自動值,谷歌出品,添加@AutoValue這樣的注解 就能夠自動生成代碼,使得程序可能更短,更清晰。 支持Java1.6+

github: https://github.com/google/auto/blob/master/value/userguide/index.md

首先看一個bean類,User.java:

public class User{  private String name;  private String addr;  private int age;  private String gender;  private String hobby;  private String sign;  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  ....(太多就省略了)}  

一堆的getter和setter代碼很多,到時候添加toString、hashCode、equals這些代碼就更麻煩了(雖然ide有快速生成),這時候AutoValue就來拯救世界了。

二、基本使用

一步一腳印

2.1 導包

初次使用需要注意,官方只說了在module依賴,這樣會build失敗的,對于新手來說會一臉懵逼,因為需要apt。

項目的build.gradle添加依賴:

dependencies {    //添加這行    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'  }

在module的build.gradle依賴以下,當前最新是1.4.1

//頂部添加apply plugin: 'com.neenbedankt.android-apt'dependencies { compile "com.google.auto.value:auto-value:1.4.1" apt "com.google.auto.value:auto-value:1.4.1"}

重新Sync即可

2.2 使用AutoValue標識bean

現(xiàn)在來重新編寫User類:

@AutoValuepublic abstract class User {  abstract String name();  abstract String addr();  abstract int age();  abstract String gender();  abstract String hobby();  abstract String sign();}

然后build -> make module一下,這時候就會生成AutoValue_User.java ,在build/generated/source/apt/debug/包名/AutoValue_User.java

里面的代碼為:

 final class AutoValue_User extends User { private final String name; private final String addr; private final int age; private final String gender; private final String hobby; private final String sign; AutoValue_User(   String name,   String addr,   int age,   String gender,   String hobby,   String sign) {  if (name == null) {   throw new NullPointerException("Null name");  }  this.name = name;  if (addr == null) {   throw new NullPointerException("Null addr");  }  this.addr = addr;  this.age = age;  if (gender == null) {   throw new NullPointerException("Null gender");  }  this.gender = gender;  if (hobby == null) {   throw new NullPointerException("Null hobby");  }  this.hobby = hobby;  if (sign == null) {   throw new NullPointerException("Null sign");  }  this.sign = sign; } @Override String name() {  return name; } @Override String addr() {  return addr; } @Override int age() {  return age; } @Override String gender() {  return gender; } @Override String hobby() {  return hobby; } @Override String sign() {  return sign; } @Override public String toString() {  return "User{"    + "name=" + name + ", "    + "addr=" + addr + ", "    + "age=" + age + ", "    + "gender=" + gender + ", "    + "hobby=" + hobby + ", "    + "sign=" + sign    + "}"; } @Override public boolean equals(Object o) {  if (o == this) {   return true;  }  if (o instanceof User) {   User that = (User) o;   return (this.name.equals(that.name()))      && (this.addr.equals(that.addr()))      && (this.age == that.age())      && (this.gender.equals(that.gender()))      && (this.hobby.equals(that.hobby()))      && (this.sign.equals(that.sign()));  }  return false; } @Override public int hashCode() {  int h = 1;  h *= 1000003;  h ^= this.name.hashCode();  h *= 1000003;  h ^= this.addr.hashCode();  h *= 1000003;  h ^= this.age;  h *= 1000003;  h ^= this.gender.hashCode();  h *= 1000003;  h ^= this.hobby.hashCode();  h *= 1000003;  h ^= this.sign.hashCode();  return h; }}

這個類就是生成的類,里面就幫你編寫好了各種方法hashCode、toStringequals、gettersetter等等。

2.3 構造方法

這時候構造方法利用自己寫的一個方法來實現(xiàn)newAutoValue_User,在User類里面添加create方法進行調用生成的AutoValue_User,這時候bean的方法這樣的:

@AutoValuepublic abstract class User {  abstract String name();  abstract String addr();  abstract int age();  abstract String gender();  abstract String hobby();  abstract String sign();  //創(chuàng)建User,內(nèi)部調用的是AutoValue_User  static User create(String name,String addr,int age,String gender,String hobby,String sign){    return new AutoValue_User(name,addr,age,gender,hobby,sign);  }}

2.4 使用

使用User.create方法即可創(chuàng)建對應User對象:

public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    User user = User.create("天平","廣東",21,"男","敲代碼","沒有個性簽名");    Log.e("@@", "onCreate: "+user.toString());  }}

即可看到輸出

onCreate: User{name=天平, addr=廣東, age=21, gender=男, hobby=敲代碼, sign=沒有個性簽名}

三、擴展api

你以為AutoValue的功能就那么少嗎 ? 錯,他還有很多擴展api。

3.1 auto-value-parcel

當User需要實現(xiàn)Parcelable接口的時候,AutoValue也可以幫你搞定了。

在基本的使用基礎上繼續(xù)導包(當前最新是0.2.5):

github地址:https://github.com/rharter/auto-value-parcel

apt 'com.ryanharter.auto.value:auto-value-parcel:0.2.5'// 需要自定義TypeAdapter就要導入compile 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.5'

基本Parcelable

這時候把User實現(xiàn)接口即可:

@AutoValuepublic abstract class User implements Parcelable{  abstract String name();  abstract String addr();  abstract int age();  abstract String gender();  abstract String hobby();  abstract String sign();  static User create(String name,String addr,int age,String gender,String hobby,String sign){    return new AutoValue_User(name,addr,age,gender,hobby,sign);  }}

重新make一下moduel即可看到生成的AutoValue_User繼承的原來的$AutoValue_User類,把Parcelable需要實現(xiàn)的方法放在了AutoValue_User類:

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.readString(),     in.readString(),     in.readInt(),     in.readString(),     in.readString(),     in.readString()   );  }  @Override  public AutoValue_User[] newArray(int size) {   return new AutoValue_User[size];  } }; AutoValue_User(String name, String addr, int age, String gender, String hobby, String sign) {  super(name, addr, age, gender, hobby, sign); } @Override public void writeToParcel(Parcel dest, int flags) {  dest.writeString(name());  dest.writeString(addr());  dest.writeInt(age());  dest.writeString(gender());  dest.writeString(hobby());  dest.writeString(sign()); } @Override public int describeContents() {  return 0; }}

其他類型Parcelable

Parcel 這個擴展支持Parcel類支持的所有類型,但有時您可能需要parcel其他類型,如SparseArray或ArrayMap。您可以使用自定義TypeAdapter執(zhí)行此操作(需要導入auto-value-parcel-adapter)

例如User里面有一個類型Date。這時候需要為Date定義一個TypeAdapters:

public class DateTypeAdapter implements TypeAdapter<Date> {  public Date fromParcel(Parcel in) {    return new Date(in.readLong());  }  public void toParcel(Date value, Parcel dest) {    dest.writeLong(value.getTime());  }}

然后User添加Date類型:

@AutoValuepublic abstract class User implements Parcelable{  abstract String name();  abstract String addr();  abstract int age();  abstract String gender();  abstract String hobby();  abstract String sign();  //需要注解自定義的TypeAdapter  @ParcelAdapter(DateTypeAdapter.class)  public abstract Date date();  static User create(String name,String addr,int age,String gender,String hobby,String sign,Date date){    return new AutoValue_User(name,addr,age,gender,hobby,sign,date);  }}

這里為延遲數(shù)據(jù)傳遞,新建一個SecondActivity,在MainActivit傳遞user過去

MainActivity.java

public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    User user = User.create("天平","廣東",21,"男","敲代碼","沒有個性簽名",new Date());    startActivity(new Intent(this,SecondActivity.class).putExtra("bean",user));  }}

SecondActivity.java

public class SecondActivity extends Activity {  @Override  protected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    User user = getIntent().getParcelableExtra("bean");    Log.e("@@two", "onCreate: "+user.toString());  }}

即可看到輸出:

E/@@: onCreate: User{name=天平, addr=廣東, age=21, gender=男, hobby=敲代碼, sign=沒有個性簽名, date=Mon Mar 13 14:36:19 GMT+08:00 2017}

3.2 auto-value-gson

就是你的用了AutoValues來修飾定義了Bean對象,Gson的就不能按照平常的方式來解析了,需要改變一下。

普及知識:

  • Gson的TypeAapter可以理解成自定義序列化和返序列化。通過實現(xiàn)JsonSerializer和JsonDeserializer進行序列化和反序列化,在Gson創(chuàng)建的時候registerTypeAdapter(你的自定義TypeAapter)。 具體請百度。

auto-value-gson 的github地址: https://github.com/rharter/auto-value-gson

導包(當前最新是0.4.6,注意,使用需要Gson,就是也要有Gson的包存在)

apt 'com.ryanharter.auto.value:auto-value-gson:0.4.6'provided 'com.ryanharter.auto.value:auto-value-gson:0.4.6'compile 'com.google.code.gson:gson:2.8.0'

3.2.1 在Bean類添加TypeAdapter

Gson解析AutoValue修飾的對象,

這時候User是這樣的:

@AutoValuepublic abstract class User implements Parcelable{abstract String name();abstract String addr();abstract int age();abstract String gender();abstract String hobby();abstract String sign();//需要注解自定義的TypeAdapter@ParcelAdapter(DateTypeAdapter.class)public abstract Date date();//添加一個TypeAdapter<User>,這個TypeAdapter是Gson包里面的。public static TypeAdapter<User> typeAdapter(Gson gson){// AutoValue_User.GsonTypeAdapter 需要先make一下module之后才會生成return new AutoValue_User.GsonTypeAdapter(gson).setDefaultAddr("默認地址"); //還可以設置默認值}}
  • 注意: TypeAdapter,這個TypeAdapter是Gson包里面的。AutoValue_User.GsonTypeAdapter(gson) 需要先make一下module之后才會生成。

3.2.2 編寫TypeAdapterFactory

然后編寫對應的編寫TypeAdapterFactory類,使用@GsonTypeAdapterFactory注解去修飾。

@GsonTypeAdapterFactorypublic abstract class UserAdapterFactory implements TypeAdapterFactory {// 靜態(tài)工廠方式public static TypeAdapterFactory create() {return new AutoValueGson_UserAdapterFactory();}}

3.2.3 Gson解析

上面搞好了之后,嘗試來解析json為User看看。

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//json字符串String json = "{/"name/":/"天平/",/"addr/":/"廣東/",/"age/":21,/"gender/":/"男/",/"hobby/":/"打代碼/",/"sign/":/"簽名/",/"date/":/"2017-3-13 14:36:19/"}";//初始化GsonGson gson = new GsonBuilder().registerTypeAdapterFactory(UserAdapterFactory.create()) //注冊自定義的TypeAdapterFactory.setDateFormat("yyyy-MM-dd HH:mm:ss") //設置json里面的Date格式.create();//開始解析User user = gson.fromJson(json,User.class);//輸出結果Log.e("@@", "onCreate: "+user.toString());}}

即可看到:

onCreate: User{name=天平, addr=廣東, age=21, gender=男, hobby=打代碼, sign=簽名, date=Mon Mar 13 14:36:19 GMT+08:00 2017}

四、小細節(jié)

4.1 Gson泛型支持

如果你的bean類里面有泛型,這時候你的TypeAdapter也需要泛型,還要添加參數(shù)TypeToken,例如:

@AutoValue public abstract class Foo<A, B, C> {abstract A data();abstract List<B> dataList();abstract Map<String, List<C>> dataMap();public static <A, B, C> TypeAdapter<Foo<A, B, C>> typeAdapter(Gson gson,TypeToken<? extends Foo<A, B, C>> typeToken) {return new AutoValue_Foo.GsonTypeAdapter(gson, typeToken);}}

4.2 可選配置

添加了下面的設置,maps/collections將默認為它們的空類型(例如List - > Collections.emptyList()) 值為true或false。

apt {arguments {autovaluegson.defaultCollectionsToEmpty 'true'}}

4.3 AutoValue plugin插件

可以生成create Builder等代碼,不過不能生成TypeAdapter代碼:

插件倉庫搜索: AutoValue plugin

開源地址: https://github.com/afcastano/AutoValuePlugin

使用方法: 安裝插件重啟了As之后,在Bean里面Alt+回車 即可ADD

4.4 配合SqlDelight

AutoValue配合SqlDelight效果會更好噢。

五 setter方法變種實現(xiàn)

AutoValue修飾的類是都是immutable不變的,所以就沒有了setter的方法。 我們應該怎么樣補救呢?

方法1: 重新new

這種情況適用于 不是頻繁的需要setter的話,重新new是個不錯的方法。

例如還是上面的bean,添加了兩個create方法,和Builder。第二個create方法就可以用來重新new,然后setter最新的數(shù)據(jù)進來:

@AutoValuepublic abstract class User {abstract String name();abstract String addr();abstract int age();abstract String gender();abstract String hobby();abstract String sign();//創(chuàng)建方法public static User create(String name, String addr, int age, String gender, String hobby, String sign) {return builder().name(name).addr(addr).age(age).gender(gender).hobby(hobby).sign(sign).build();}//setter的時候傳遞當前的user過來,這里重新builder,再設置public static Builder create(User user){return builder().name(user.name()).addr(user.addr()).age(user.age()).gender(user.gender()).hobby(user.hobby()).sign(user.sign());}public static Builder builder() {return new AutoValue_User.Builder();}@AutoValue.Builderpublic abstract static class Builder {public abstract Builder name(String name);public abstract Builder addr(String addr);public abstract Builder age(int age);public abstract Builder gender(String gender);public abstract Builder hobby(String hobby);public abstract Builder sign(String sign);public abstract User build();}}

使用,例如我要更新簽名:

private void updateSign(User user){    user = User.create(user).sign("新簽名").build();  }

方法2: 不要用AutoValue了

這種情況適用于你需要頻繁的調用setter,如果用第一種方案的話,就需要頻繁的new對象,對程序效率有大大的影響。

總結

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VEVB武林網(wǎng)的支持。


注:相關教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 鹤庆县| 临颍县| 商南县| 彭山县| 白朗县| 阿坝| 沅江市| 双峰县| 玉溪市| 吐鲁番市| 图们市| 渑池县| 定安县| 乡城县| 温宿县| 泸定县| 正镶白旗| 丽水市| 孟州市| 安阳县| 额济纳旗| 兴隆县| 新安县| 香港| 洛扎县| 栾城县| 微山县| 阿勒泰市| 南丹县| 乌恰县| 大荔县| 丰镇市| 定襄县| 金山区| 丰城市| 双桥区| 高密市| 宝坻区| 徐水县| 海盐县| 米脂县|