Android Parcelable 序列化 的时候:已经序列化的对象, 数组,boolean,Bitmap;

parcelable序列化 :对象,数组,boolean,bitmap;

一、序列化分为:序列化过程  和 反序列化过程:
一)序列化过程:

 //序列化过程   一系列write方法  
 //其中flags标识有两种值:0或者1,
 // 1 === 标识当前对象需要作为返回值返回,
 // 0 === 不能立即释放资源,几乎所有情况都为0
    public void writeToParcel(Parcel out,int flags){
        out.writeInt(...);
        out.writeString(...);
        out.writeInt(isMan?1:0);
        out.writeParcelable(son,0);
    }

二)反序列化:
//反序列化过程
    public static final Parcelable.Creator<Person> CREATOR=new Parcelable.Creator<Person>(){
        //从序列化后的对象中创建原始对象
        public Person createFromParcel(Parcel in){
            return new Person(in);
        }
        //创建指定长度的原始对象数组
        public Person[] newArray(int size){
            return new Person[size];
        }
    };
    //由于book是另一个可序列化对象,所以它的反序列化过程需要传递当前线程的上下文类加载器,否则会报无法找到类的错误
    private Person(Parcel in){
        userId =in.readInt();
        userName=in.readString();
        isMan=in.readInt()==1;
        son=in.readParcelable(Thread.currentThread().getContentClassLoader());
    }






下面为一个例子

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

public class Person implements Parcelable{

	public String name ;
	public int age ;
	public String[] msg ;
	public int garde ;
	public Son son ;
	private boolean isMan;
	
	@Override
	public int describeContents() {
		Log.v("Tag", " describeContents ");
		return 0;
	}
	
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		Log.v("Tag", this+" ------> writeToParcel "+flags);
		//这里是把对象的字段一个一个写到流里面,写的顺序要和下面读的顺序一摸一样
		
		dest.writeInt(age);
		dest.writeString(name);
		
		//这几句话是写数组的,因为数组的长度不确定,所以先确定数组长度,如果为空就不写,但是要把0 给发过去
		//让下面的好判断能不能读数组,也就是说下面如果读到的长度是0,那么就不读数组了,否则就创建相同长度的数组去读
		if(msg==null){
			dest.writeInt(0);
		}else{
			dest.writeInt(msg.length);
		}
		//如果数组为空,就可以不写
		if(msg!=null){
			dest.writeStringArray(msg);
		}
		
		dest.writeInt(garde);
		dest.writeParcelable(son, flags);
		dest.writeInt(isMan?1:-1);//是 就传递1,否则传递-1
	}
	
	public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
		
		@Override
		public Person[] newArray(int size) {
			Log.w("Tag", " person new Array : "+size);
			return new Person[size];
		}
		
		@Override
		public Person createFromParcel(Parcel source) {

			return new Person(source) ;
		}
	};
	
	private Person(Parcel source){
					//开始读对象的流顺序要和上面写的一样
			Log.w("Tag", " createFromParcel ");
			 age = source.readInt();
			 name = source.readString() ;
			
			//开始读数组的长度 
			int length = source.readInt() ;
			Log.v("Tag", " length : "+length);
			String[] msg = null ;
			//如果数组长度大于0,那么就读数组, 所有数组的操作都可以这样。
			if(length>0){
				msg = new String[length];
				source.readStringArray(msg);
			}
			
			 grade = source.readInt() ;
			 son = source.readParcelable(Son.class.getClassLoader());
			Log.i("Tag", " son : "+son);

			isMan = source.readInt()>0?true:false;
		
	}
	
}
序列化Bitmap:

1. 可以将Bitmap 转成 byte【】数组,然后在转换成 bitmap;

2.但是Bitmap 时已经是序列化好的了,所以可以当成 Son 进行传递;

public byte[] getBytes(Bitmap bitmap){  
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
	    bitmap.compress(Bitmap.CompressFormat.PNG, 0, baos);
	    return baos.toByteArray();
	} 
	
	public  Bitmap getBitmap(byte[] data){  
	      return BitmapFactory.decodeByteArray(data, 0, data.length);
	}
	
package com.redoor.rcs.info;

import java.io.ByteArrayOutputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * @version 1.0
 *
 * @author DongXiang
 * 
 * @action 消息列表界面,展示的条item对象;
 * <br>目前支持:单聊消息对象,
 * <br>群聊,公众账号,稍后会陆续兼容;
 * 
 * @time 2017年4月7日下午2:35:27
 * 
 */
public class MsgListInfo  implements Parcelable{

	/** 消息类型:0 = 一对一消息;1 = 公账号消息;2 = 群聊消息*/
	private int msgType;
	
	/** 聊天展示的*/
	private String title;
	
	/** <br> 1.单聊:单聊对象手机号
	 *  <br> 2.群聊:群聊的房间号
	 *  <br> 3.公众账号:公众账号的房间号
	 */
	private String chatRoomID;
	
	/** 最后一条消息,内容*/
	private String lastMsgContent;
	
	/** 是否显示警告*/
	private boolean isShowWarning;
	
	/** 这三个参数,供备用:像 handler 的 Message 的参数一样*/
	private String param1;
	/** 这三个参数,供备用:像 handler 的 Message 的参数一样*/
	private String param2;
	/** 这三个参数,供备用:像 handler 的 Message 的参数一样*/
	private String param3;
	
	/** 最后互撩消息的 时间,long类型;排序使用的*/
	private long dateLong; 
	/** 最后互撩消息的 时间,String类型;显示使用*/
	private String dateStr;
	
	/** 未读消息的条数 */
	private int unReadNum;
	
	/** 头像的图标:bitmap已经 实现了序列化Parcelable*/
	private Bitmap headBitmap;
	
	public MsgListInfo(int msgType, String title, String chatRoomID,
			String lastMsgContent, boolean isShowWarning, String param1,
			String param2, String param3, long date, String dateStr,
			int unReadNum, Bitmap headBitmap) {
		super();
		this.msgType = msgType;
		this.title = title;
		this.chatRoomID = chatRoomID;
		this.lastMsgContent = lastMsgContent;
		this.isShowWarning = isShowWarning;
		this.param1 = param1;
		this.param2 = param2;
		this.param3 = param3;
		this.dateLong = date;
		this.dateStr = dateStr;
		this.unReadNum = unReadNum;
		this.headBitmap = headBitmap;
	}

	public MsgListInfo() {
		super();
	}

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

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeInt(msgType);
		dest.writeString(title);
		dest.writeString(chatRoomID);
		dest.writeString(lastMsgContent);
		dest.writeInt(isShowWarning?1:-1);//展示就传递过去1,否则传递过去-1;
		dest.writeString(param1);
		dest.writeString(param2);
		dest.writeString(param3);
		dest.writeLong(dateLong);
		dest.writeString(dateStr);
		dest.writeInt(unReadNum);
		int len=0;
		if (headBitmap==null) {
			dest.writeInt(len);//判断bitmap 是否为空,若为空则
		}else {
			byte[] bitmapBytes=getBytes(headBitmap);
			len=bitmapBytes.length;
			dest.writeInt(len);
			dest.writeByteArray(bitmapBytes);
		}
		
	}
	
	private MsgListInfo(Parcel source) {
		msgType=source.readInt();
		title=source.readString();
		chatRoomID=source.readString();
		lastMsgContent=source.readString();
		isShowWarning=source.readInt()>0?true:false;
		param1=source.readString();
		param2=source.readString();
		param3=source.readString();
		dateLong=source.readLong();
		dateStr=source.readString();
		unReadNum=source.readInt();
		
		int len=source.readInt();
		if (len<=0) {
			headBitmap=null;
		}else {
			byte[] bitmapBytes=new byte[len];
			source.readByteArray(bitmapBytes);
			headBitmap=getBitmap(bitmapBytes);
		}
		
		
	}
	public static final Parcelable.Creator<MsgListInfo> CREATOR=new Parcelable.Creator<MsgListInfo>() {

		@Override
		public MsgListInfo createFromParcel(Parcel source) {
			// TODO Auto-generated method stub
			return new MsgListInfo(source);
		}

		@Override
		public MsgListInfo[] newArray(int size) {
			// TODO Auto-generated method stub
			return new MsgListInfo[size];
		}
		
	};
	
	
	
	private byte[] getBytes(Bitmap bitmap){  
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
	    bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
	    return baos.toByteArray();
	} 
	
	private  Bitmap getBitmap(byte[] data){  
	      return BitmapFactory.decodeByteArray(data, 0, data.length);
	}
	
	

}




扩展:

本地File 和 Bitmap 进行转化:

public void saveInputTypeEditTextDataToFile(Object object,String fileName){
		ObjectOutputStream objectOutputStream = null;
		try {
			FileOutputStream fileOutputStream = mContext.openFileOutput(fileName,Context.MODE_PRIVATE);
			objectOutputStream = new ObjectOutputStream(fileOutputStream);
			objectOutputStream.writeObject(object);
			objectOutputStream.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if (objectOutputStream != null) {
				try {
					objectOutputStream.close();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}
	
	public byte[] readBitmapDataFromFile(String fileName){
		ObjectInputStream objectInputStream = null;
		try {
			FileInputStream fileInputStream = mContext.openFileInput(fileName);
			objectInputStream = new ObjectInputStream(fileInputStream);
			byte[] editTexts = (byte[]) objectInputStream.readObject();
			return editTexts;
		} catch (StreamCorruptedException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			if (objectInputStream != null) {
				try {
					objectInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	


Tips:

一、序列化的知识点:

所谓序列化其实就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来的一种保存对象状态的机制。

二、需要序列化的情况:

1、当想把内存中的对象保存到一个文件中或者数据库中的时候;

2、当想通过RMI传输对象的时候;

3、当想用套接字在网络上传送对象时。

在没有序列化前,每个保存在Heap中的对象都有相应的状态,即实例变量,当对象序列化后,就可以将类的类型、属性的值等

相应信息被保存到***.ser文件中,这样以后就可以将它从文件中读出来,从新在Heap中创建原来的对象。

仨、对象序列化的注意事项:

1、当一个父类实现序列化,子类自动实现序列化,无需再次实现Serializable接口;

2、当一个对象的实例变量引用其他对象,序列化该对象时也会将引用对象进行序列化;

3、并非所有的对象都可以序列化(可在度娘上找到)









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值