android 序列化

package com.yunkapay.push.mobile.parcelable;


import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import com.yunkapay.push.mobile.util.Logger;

import java.lang.reflect.*;
import java.util.*;

public abstract class GlobalParcelable<T extends GlobalParcelable> implements Parcelable {


    public GlobalParcelable() {
        // TODO Auto-generated constructor stub

    }

    public GlobalParcelable(Parcel in) {
        String className = in.readString();
        Log.i("GlobalParcelable", "Constructor: " + ((Object) this).getClass().getSimpleName() + "; In parcel: " + className);

        readFromParcel(in);
    }


    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(((Object) this).getClass().getName());
        try {
            dehydrate(this, dest);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void readFromParcel(Parcel in) {
        try {
            rehydrate(this, in);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    // writes fields of a GlobalParcelable to a parcel
    // does not include the first parcelled item -- the class name
    protected void dehydrate(GlobalParcelable model, Parcel out) throws IllegalArgumentException, IllegalAccessException {
        Class<?> cla = ((Object) model).getClass();
        Log.i("GlobalParcelable", "dehydrating... " + cla.toString());
        // get the fields

        Field[] fields=getFields(cla);

        // sort the fields so it is in deterministic order
        Arrays.sort(fields, compareMemberByName);
        // populate the fields
        for (Field field : fields) {
            field.setAccessible(true);
            int modifier = field.getModifiers();
            Log.i("GlobalParcelable", "Field:" + field.getName() + " " + Modifier.isStatic(modifier) + " " + Modifier.isFinal(modifier));
            if (field.getType().equals(int.class)) {
                out.writeInt(field.getInt(model));
            } else if (field.getType().equals(double.class)) {
                out.writeDouble(field.getDouble(model));
            } else if (field.getType().equals(float.class)) {
                out.writeFloat(field.getFloat(model));
            } else if (field.getType().equals(long.class)) {
                out.writeLong(field.getLong(model));
            } else if (field.getType().equals(String.class)) {
                out.writeString((String) field.get(model));
            } else if (field.getType().equals(boolean.class)) {
                out.writeByte(field.getBoolean(model) ? (byte) 1 : (byte) 0);
            } else if (field.getType().equals(Date.class)) {
                Date date = (Date) field.get(model);
                if (date != null) {
                    out.writeLong(date.getTime());
                } else {
                    out.writeLong(0);
                }
            } else if (GlobalParcelable.class.isAssignableFrom(field.getType())) {
                // why did this happen?
                Log.e("GlobalParcelable", "GlobalParcelable F*ck up: " + " (" + field.getType().toString() + ")");
                out.writeParcelable((GlobalParcelable) field.get(model), 0);
            } else {
                // wtf
                Log.e("GlobalParcelable", "Could not write field to parcel: " + " (" + field.getType().toString() + ")");
            }
        }
    }

    protected static Field[] getFields(Class<?> cla) {
        List<Field> fieldList = new ArrayList<Field>();
        do {
            Logger.d("Class "+cla.toString());
            Field[] fields = cla.getDeclaredFields();
            for (Field f : fields) {
                int modifier = f.getModifiers();
                if (Modifier.isStatic(modifier) && Modifier.isFinal(modifier)) {
                    Logger.d("final static value "+f.getName());
                } else {
                    fieldList.add(f);
                }
            }
            cla = cla.getSuperclass();
        } while (cla != null && !GlobalParcelable.class.equals(cla));

        return fieldList.toArray(new Field[fieldList.size()]);
    }

    // reads the parcelled items and put them into this object's fields
    // must be run after getting the first parcelled item -- the class name
    protected static void rehydrate(GlobalParcelable model, Parcel in) throws IllegalArgumentException, IllegalAccessException {
        Class<?> cla = ((Object) model).getClass();
        Log.i("GlobalParcelable", "rehydrating... " + cla.toString());
        // get the fields
        Field[] fields =getFields(cla);
        // sort the fields so it is in deterministic order
        Arrays.sort(fields, compareMemberByName);
        // populate the fields
        for (Field field : fields) {

            field.setAccessible(true);
            if (field.getType().equals(int.class)) {
                field.set(model, in.readInt());
            } else if (field.getType().equals(double.class)) {
                field.set(model, in.readDouble());
            } else if (field.getType().equals(float.class)) {
                field.set(model, in.readFloat());
            } else if (field.getType().equals(long.class)) {
                field.set(model, in.readLong());
            } else if (field.getType().equals(String.class)) {
                field.set(model, in.readString());
            } else if (field.getType().equals(boolean.class)) {
                field.set(model, in.readByte() == 1);
            } else if (field.getType().equals(Date.class)) {
                Date date = new Date(in.readLong());
                field.set(model, date);
            } else if (GlobalParcelable.class.isAssignableFrom(field.getType())) {
                Log.e("GlobalParcelable", "read GlobalParcelable: " + " (" + field.getType().toString() + ")");
                field.set(model, in.readParcelable(field.getType().getClassLoader()));
            } else {
                // wtf
                Log.e("GlobalParcelable", "Could not read field from parcel: " + field.getName() + " (" + field.getType().toString() + ")");
            }
        }
    }


    /*
     * Comparator object for Members, Fields, and Methods
     */
    private static Comparator<Field> compareMemberByName =
            new CompareMemberByName();

    private static class CompareMemberByName implements Comparator {
        public int compare(Object o1, Object o2) {
            String s1 = ((Member) o1).getName();
            String s2 = ((Member) o2).getName();

            if (o1 instanceof Method) {
                s1 += getSignature((Method) o1);
                s2 += getSignature((Method) o2);
            } else if (o1 instanceof Constructor) {
                s1 += getSignature((Constructor) o1);
                s2 += getSignature((Constructor) o2);
            }
            return s1.compareTo(s2);
        }
    }


    /**
     * Compute the JVM signature for the class.
     */
    private static String getSignature(Class clazz) {
        String type = null;
        if (clazz.isArray()) {
            Class cl = clazz;
            int dimensions = 0;
            while (cl.isArray()) {
                dimensions++;
                cl = cl.getComponentType();
            }
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < dimensions; i++) {
                sb.append("[");
            }
            sb.append(getSignature(cl));
            type = sb.toString();
        } else if (clazz.isPrimitive()) {
            if (clazz == Integer.TYPE) {
                type = "I";
            } else if (clazz == Byte.TYPE) {
                type = "B";
            } else if (clazz == Long.TYPE) {
                type = "J";
            } else if (clazz == Float.TYPE) {
                type = "F";
            } else if (clazz == Double.TYPE) {
                type = "D";
            } else if (clazz == Short.TYPE) {
                type = "S";
            } else if (clazz == Character.TYPE) {
                type = "C";
            } else if (clazz == Boolean.TYPE) {
                type = "Z";
            } else if (clazz == Void.TYPE) {
                type = "V";
            }
        } else {
            type = "L" + clazz.getName().replace('.', '/') + ";";
        }
        return type;
    }


    /*
     * Compute the JVM method descriptor for the method.
     */
    private static String getSignature(Method meth) {
        StringBuffer sb = new StringBuffer();

        sb.append("(");

        Class[] params = meth.getParameterTypes(); // avoid clone
        for (int j = 0; j < params.length; j++) {
            sb.append(getSignature(params[j]));
        }
        sb.append(")");
        sb.append(getSignature(meth.getReturnType()));
        return sb.toString();
    }

    /*
     * Compute the JVM constructor descriptor for the constructor.
     */
    private static String getSignature(Constructor cons) {
        StringBuffer sb = new StringBuffer();

        sb.append("(");

        Class[] params = cons.getParameterTypes(); // avoid clone
        for (int j = 0; j < params.length; j++) {
            sb.append(getSignature(params[j]));
        }
        sb.append(")V");
        return sb.toString();
    }
}

  

package com.yunkapay.push.mobile.notification;

import android.os.Parcel;
import android.os.Parcelable;
import com.yunkapay.push.mobile.parcelable.GlobalParcelable;
import com.yunkapay.push.mobile.util.Logger;
import org.json.JSONObject;

/**
 * Created with IntelliJ IDEA.
 * User: zac
 * Date: 12/2/13
 * Time: 2:26 PM
 * To change this template use File | Settings | File Templates.
 */
public class XJNotification extends GlobalParcelable {
    public static final String ELEMENT_NAME = "notification";
    public static final String NAMESPACE = "pubsub:message:notification";
    public static final String NOTIFICATION_NODE = "node";
    public static final String NOTIFICATION_ID = "id";
    public static final String NOTIFICATION_TITLE = "title";
    public static final String NOTIFICATION_CONTENT = "content";
    public static final String NOTIFICATION_TYPE = "type";
    public static final String NOTIFICATION_IMAGE_URL = "image_url";
    public static final String NOTIFICATION_LINK = "link";
    public static final String NOTIFICATION_TIME = "time";
    public static final String NOTIFICATION_TIME_TO_LIVE = "time_to_live";

    public String mNotificationID;
    public String mNode;
    public String mTitle;
    public String mContent;
    public long mTime;
    public int mTimeToLive;


    public XJNotification(JSONObject jsonObject) {

    }

    public XJNotification() {
        super();
    }

    public static final Parcelable.Creator<XJNotification> CREATOR = new Parcelable.Creator<XJNotification>() {
        public XJNotification createFromParcel(Parcel in) {
            // get class from first parcelled item
            Class<?> parceledClass;
            try {
                parceledClass = Class.forName(in.readString());
                Logger.i("Creator: " + parceledClass.getSimpleName());
                // create instance of that class
                XJNotification model = (XJNotification) parceledClass.newInstance();
                rehydrate(model, in);
                return model;
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

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

    public String getNotificationID() {
        return this.mNotificationID;
    }

    public String getNode() {
        return this.mNode;
    }

    public String getTitle() {
        return this.mTitle;
    }


    public String getContent() {
        return this.mContent;
    }

    public static String getElementName() {
        return ELEMENT_NAME;
    }

    public long getTime() {
        return this.mTime;
    }

    public int getTimeToLive() {
        return this.mTimeToLive;
    }

    public void setNotificationID(String notificationID) {
        this.mNotificationID = notificationID;
    }

    public void setNode(String node) {
        this.mNode = node;
    }

    public void setTitle(String title) {
        this.mTitle = title;
    }

    public void setContent(String content) {
        this.mContent = content;
    }

    public void setTime(long time) {
        this.mTime = time;
    }

    public void setTimeToLive(int timeToLive) {
        this.mTimeToLive = timeToLive;
    }

    public NotificationType getType() {
        return NotificationType.UNKNOWN;
    }


}
相關文章
相關標籤/搜索