• [原创]如何在Parcelable中使用泛型


    [原创]如何在Parcelable中使用泛型

    实体类在实现Parcelable接口时,除了要实现它的几个方法之外,还另外要定义一个静态常量CREATOR,如下例所示:

     1     public static class ProductModel implements Parcelable {
     2         public String id;
     3         public String title;
     4         public String sold_num;
     5         public String max_month;
     6         public String cprice;
     7         public double month_price;
     8         public List<String> gpic;
     9 
    10         @Override
    11         public int describeContents() {
    12             return 0;
    13         }
    14 
    15         @Override
    16         public void writeToParcel(Parcel dest, int flags) {
    17             dest.writeString(this.id);
    18             dest.writeString(this.title);
    19             dest.writeString(this.sold_num);
    20             dest.writeString(this.max_month);
    21             dest.writeString(this.cprice);
    22             dest.writeDouble(this.month_price);
    23             dest.writeStringList(this.gpic);
    24         }
    25 
    26         public ProductModel() {
    27         }
    28 
    29         protected ProductModel(Parcel in) {
    30             this.id = in.readString();
    31             this.title = in.readString();
    32             this.sold_num = in.readString();
    33             this.max_month = in.readString();
    34             this.cprice = in.readString();
    35             this.month_price = in.readDouble();
    36             this.gpic = in.createStringArrayList();
    37         }
    38 
    39         public static final Creator<ProductModel> CREATOR = new Creator<ProductModel>() {
    40             public ProductModel createFromParcel(Parcel source) {
    41                 return new ProductModel(source);
    42             }
    43 
    44             public ProductModel[] newArray(int size) {
    45                 return new ProductModel[size];
    46             }
    47         };

    CREATOR在这里成为了一个约定,而没有放到接口定义里面,个人感觉这样封装得不是很好,不知道是不是实在没有更好的解决办法才弄成这样的?

    假如在类里要使用泛型,麻烦就来了,例如这样

     1 public class PageDataModel<T extends Parcelable> extends APIDataModel {
     2 
     3     static final String DATA_KEY = "data";
     4 
     5     /**
     6      * count : 1
     7      * total_pages : 1
     8      * list_rows : 10
     9      * first_row : 0
    10      */
    11 
    12     public int count;
    13     public ArrayList<T> data;
    14     public int total_pages;
    15     public int list_rows;
    16     public int first_row;
    17 }

    这个data,就无法正常read(write倒是可以)。

    正常的write方式是这样的:

    this.data = dest.createTypedArrayList(Parcelable.Creator<T> c)

    那么问题来了,你只有一个泛型T,没有具体类型,拿不到它的CREATOR!CREATOR只是一个约定,而且是跟具体类型绑定的。

    所以我前面说如果这个CREATOR能通过某种方式定义下来,这里或许就能拿到了,然而并没有。

    但是android系统你是改变不了的,我们仍然要解决问题。经过多番调查尝试之后,终于找到了解决办法:

    Pacel是可以读取和写入Bundle对象的,而Bundle对象又可以读取和写入Parcelable,而且不需要CREATOR(为啥Parcel不能设计成这样,坑爹呢。。)

    那么 我们把泛型数据用Bundle包装一下即可,下面是具体代码,亲测有效,总算解决这个问题了。

    1 //write
    2 Bundle bundle = new Bundle();
    3 bundle.putParcelableArrayList(DATA_KEY, data);
    4 dest.writeBundle(bundle);
    5 
    6 //read
    7 this.data = in.readBundle().getParcelableArrayList(DATA_KEY);
  • 相关阅读:
    loj#2540. 「PKUWC2018」随机算法
    loj#2538. 「PKUWC2018」Slay the Spire
    loj#2537. 「PKUWC2018」Minimax
    CF662C Binary Table
    bzoj4589: Hard Nim
    【HDU5909】Tree Cutting(FWT)
    P3175 [HAOI2015]按位或
    P4389 付公主的背包
    P4233 射命丸文的笔记
    GFS分布式文件系统环境部署与管理
  • 原文地址:https://www.cnblogs.com/DarkMaster/p/4975025.html
Copyright © 2020-2023  润新知