用parcel解决intent传递大数据

1.前言

       前阵子遇到一个问题,批量设置商品的价格当选中的商品非常多时,app崩溃了,但是当选中的商品很少时却没问题,直觉告诉我是intent对传递数据的大小有限制,果然一百度发现intent对传递的数据大小有限制,具体可以看看这篇博客,写的非常好http://m.blog.csdn.net/article/details?id=52528087

2.过程

       知道了问题所在,就照着网上说的方法尝试修改bug,用静态static,效率很高,但是会破坏程序的独立性(常用)。后来感觉不是很好,于是在谷歌上找到一种代替方法(http://www.cnblogs.com/androidsuperman/p/4178030.html

于是在自家的工程里创建了FlashIntentUtils 类开始使用了这个全局的单例。因为要传递2个参数ArrayList<String> ids 和 ArrayList<GoodsVo> goods所以自己写的FlashIntentUtils是和 ArrayList<GoodsVo> goods所以自己写的FlashIntentUtils是

public class FlashIntentUtils {
    private static volatile FlashIntentUtils instance = null;

    private FlashIntentUtils(){
    }

    public static FlashIntentUtils getInstance() {
        if (instance == null) {
            synchronized (FlashIntentUtils.class) {
                if (instance == null) {
                    instance = new FlashIntentUtils();
                }
            }
        }

        return instance;
    }
    private Object object;
    public void putExtra(Object object) {
        this.object = object;
    }
    public Object getExtra() {
        Object extra = object;
        this.object = null;
        return extra;
    }

    private Object objectone;
    public void putOneExtra(Object objectone) {
        this.objectone = objectone;
    }
    public Object getOneExtra() {
        Object extra = objectone;
        this.objectone = null;
        return extra;
    }
}

传递参数

FlashIntentUtils.getInstance().putExtra(ids);
FlashIntentUtils.getInstance().putOneExtra(goods);

接收参数

this.ids = (ArrayList<String>) FlashIntentUtils.getInstance().getExtra();
this.goods = (ArrayList<GoodsVo>) FlashIntentUtils.getInstance().getOneExtra();
但是发现这个全局的类可能存在线程不安全,虽然这个方法只是在A.activity跳转到B.activity是用,一般不会有问题,但是还是存在理论上的问题。发现这几种方法确实不怎么好,后来请教了下前辈,他说可以用parcel。呐呢?parcel!我只是知道parcel和Serializable差不多都是用来传递参数的,只是parcel传递参数更加麻烦,并不知道parcel能传递大数据,前辈也不确定,所以就自己动手试一试。

       一开始当然是百度parcel的用法,这里有几遍文章不错我也就不说了,看完大家差不多都懂了:Android Activity间传值(http://www.jianshu.com/p/3da56fdca7c8;http://blog.csdn.net/android_tutor/article/details/5740845),大家注意如果想在页面上用ParcelableGood parcelableGood = new ParcelableGood();不能在ParcelableGood里定义private ParcelableGood(parcel in)方法,话不多说直接上源码

传递参数

                    ParcelableGood parcelableGood = new ParcelableGood();
                    ArrayList<String> ids = (ArrayList<String>) getIds();
//                  String goodsList = goods.toString();
                    parcelableGood.setIds(ids);
//                  parcelableGood.setGoodsList(goodsList);
                    Intent intent = new Intent();
                    intent.setClass(this, StockRemindGoodsSaveSettingActivity.class);
                    intent.putParcelableArrayListExtra("goods", goods);
                    intent.putExtra("goodids",parcelableGood);
                    startActivityForResult(intent,100);           

接收参数

         Object parcelable = getIntent().getParcelableExtra("goodids");
         if(parcelable != null && parcelable instanceof ParcelableGood){
               ParcelableGood parcelableGood = (ParcelableGood) parcelable;
               ids = new  ArrayList(parcelableGood.getIds());
         }
         goods = getIntent().getParcelableArrayListExtra("goods");
ParcelableGood 类

public class ParcelableGood implements Parcelable {


    private List<String> ids;
    private String goodsList;

    public List<String> getIds() {
        return ids;
    }

    public void setIds(List<String> ids) {
        this.ids = ids;
    }

    public String getGoodsList() {
        return goodsList;
    }

    public void setGoodsList(String goodsList) {
        this.goodsList = goodsList;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStringList(ids);
        dest.writeString(goodsList);
    }
    public static final Parcelable.Creator<ParcelableGood> CREATOR = new Creator<ParcelableGood>(){

        @Override
        public ParcelableGood createFromParcel(Parcel in) {
            ParcelableGood mparcelableGood = new ParcelableGood();
            mparcelableGood.ids = in.createStringArrayList();
            mparcelableGood.goodsList = in.readString();
            return  mparcelableGood;
        }

        @Override
        public ParcelableGood[] newArray(int size) {
            return new ParcelableGood[size];
        }
    };
//
//    private ParcelableGood(Parcel in){
//        ids = in.readString();
//        goodsList = in.readString();
//    }

}

      因为goods的参数类型是ArrayList<GoodsVo>,parcel是支持直接的数组传递的( intent.putParcelableArrayListExtra("goods", goods);),所以GoodsVo的参数由原来的public class GoodsVo implements Serializable变成了public class GoodsVo implements Parcelable另外在加上Parcelable继承的方法

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(barCode);
    dest.writeString(goodsId);
    dest.writeString(goodsName);
    dest.writeInt(type);
    dest.writeString(retailPrice);
    dest.writeInt(upDownStatus);
    dest.writeString(filePath);
}

public static final Parcelable.Creator<GoodsVo> CREATOR = new Creator<GoodsVo>() {
    @Override
    public GoodsVo createFromParcel(Parcel source) {
        GoodsVo goodsVo = new GoodsVo();
        goodsVo.barCode = source.readString();
        goodsVo.goodsId = source.readString();
        goodsVo.goodsName = source.readString();
        goodsVo.type = source.readInt();
        goodsVo.retailPrice = source.readString();
        goodsVo.upDownStatus = source.readInt();
        goodsVo.filePath = source.readString();
        return goodsVo;
    }

    @Override
    public GoodsVo[] newArray(int size) {
        return new GoodsVo[size];
    }
};

       在writeToParcel方法中也不需要把所有的GoodsVo里的参数都写进去,只要把需要传递的参数写入就可以了。需要注意的是,如果继承parcel的类中有数组变量入上面ParcelableGood里的List<String> ids;在写入时dest.writeStringList(ids);在读时用  mparcelableGood.ids = in.createStringArrayList();具体的看上面的代码^ ^。

3.测试

        经过一些努力终于完成了,经过测试当选中1000+商品时,也能在2个activity间传递参数,而且效率很高,响应速度很快,解决了TransactionTooLargeException问题。

4.总结

       虽然在一开始就已经找到了解决方案,但是我感觉做安卓不应该只是把业务做完,而是应该把软件做好,遇到问题,找到更好的解决方法很重要,虽然用parcel解决intent传递大数据的问题也可能不是最优解,但我还是尽力了,毕竟我自己还是很菜的,身边的资源也不是很多,非常乐意大家指出不足一起讨论,如果能提供更好的解决方案,我会更高兴的,谢谢大家,还有身边的所以人~~

                                                                                                                                转载请注明出处  2017.04.10  18:18

                                                                                                                                                                           ——YF


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 使用 Bundle 传递数据: ```java // 发送方 Intent intent = new Intent(this, LoginActivity.class); Bundle bundle = new Bundle(); bundle.putString("username", "username"); bundle.putString("password", "password"); bundle.putBoolean("isLogin", true); intent.putExtras(bundle); startActivity(intent); // 接收方 Bundle bundle = getIntent().getExtras(); String username = bundle.getString("username"); String password = bundle.getString("password"); boolean isLogin = bundle.getBoolean("isLogin"); ``` 2. 使用 Intent 传递数据: ```java // 发送方 Intent intent = new Intent(this, LoginActivity.class); intent.putExtra("username", "username"); intent.putExtra("password", "password"); intent.putExtra("isLogin", true); startActivity(intent); // 接收方 String username = getIntent().getStringExtra("username"); String password = getIntent().getStringExtra("password"); boolean isLogin = getIntent().getBooleanExtra("isLogin", false); ``` 3. 使用 Parcelable 传递数据: ```java // 发送方 Intent intent = new Intent(this, LoginActivity.class); User user = new User("username", "password", true); intent.putExtra("user", user); startActivity(intent); // 接收方 User user = getIntent().getParcelableExtra("user"); // User 类的实现 public class User implements Parcelable { private String username; private String password; private boolean isLogin; public User(String username, String password, boolean isLogin) { this.username = username; this.password = password; this.isLogin = isLogin; } protected User(Parcel in) { username = in.readString(); password = in.readString(); isLogin = in.readByte() != 0; } public static final Creator<User> CREATOR = new Creator<User>() { @Override public User createFromParcel(Parcel in) { return new User(in); } @Override public User[] newArray(int size) { return new User[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(username); dest.writeString(password); dest.writeByte((byte) (isLogin ? 1 : 0)); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值