简体   繁体   中英

How to get rid of implementing Parcelable for each class in android in order to use it for put extra array list

是否可以一次实现一个Parcelable类并将其用于所有其他类,以便在活动之间传递带有额外数组列表的List?

与其使用反射,不如将其序列化为JSON字符串(使用GSON库)并反序列化为目标类上的Object并非更好。

Don't fight the system. Using Reflection or JSON has an impact on performance. Go ahead with the Parcelable and use a helper site like http://www.parcelabler.com/ or an Android Studio plugin like https://github.com/mcharmas/android-parcelable-intellij-plugin

Yes , with reflection.

import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.lang.reflect.Field;
import java.util.ArrayList;

public class ParcelableEntity implements Parcelable {
    private static final String TAG = "ParcelableEntity";

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

    @Override
    public void writeToParcel(Parcel destination, int flags) {

        destination.writeString(this.getClass().getCanonicalName());

        for (Field field : this.getClass().getDeclaredFields()) {
            try {
                field.setAccessible(true);
                if (field.getType().equals(java.util.List.class)) {
                    destination.writeList((ArrayList) field.get(this));
                } else
                    destination.writeValue(field.get(this));
            } catch (Exception err) {
                Log.w(TAG, err.toString());
            }

        }

    }

    public static final Creator CREATOR = new Creator() {
        public ParcelableEntity createFromParcel(Parcel source) {
            try {
                Object entity = Class.forName((source.readString())).newInstance();

                for (Field field : entity.getClass().getDeclaredFields()) {
                    try {
                        field.setAccessible(true);
                        if (field.getType().equals(java.util.List.class)) {
                            ArrayList list = new ArrayList();
                            source.readList(list, Class.forName(field.getDeclaringClass().getName()).getClassLoader());
                            field.set(entity, list);
                        } else
                            field.set(entity, source.readValue(field.getType().getClassLoader()));

                    } catch (Exception err) {
                        Log.w(TAG, err.toString());
                    }
                }

                return (ParcelableEntity) entity;

            } catch (Exception err) {
                return null;
            }
        }

        public ParcelableEntity[] newArray(int size) {
            return new ParcelableEntity[size];
        }
    };

} 

And now you should extend it in your class

public class Book extends ParcelableEntity {

    public Long id;
    public String name;
}

And then use it

public void onClick(View view) {
        ArrayList<book> lstBook = new ArrayList<>();
        Book b1 = new Book();
        b1.id = 1L;
        b1.name = "test 1";
        lstBook.add(b1);
        Book b2 = new Book();
        b2.id = 2L;
        b2.name = "test 2";       
        lstBook.add(b2);

        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        intent.putParcelableArrayListExtra("TEST", lstBook);
        startActivity(intent);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM