序列化手段(2)——Serializable和Parcelable的实现演示

如果都了解过Parcel类的实现,那么其基本只序列化基本类型的特性还不能满足我们的需求(事实上android中Binder的IPC通信中,Parcel对象也能传递Parcel对象,现实编程用得极少)。具体的Parcel类这里不做介绍。点击查看Parcel类详解

Serializable和Parcelable在现实中的应用场景,有个网友写得非常nice,强烈推荐大家有空看下。点击查看Serializable和Parcelable你应该懂得的几个应用场景

之前学习java的时候,实现Serializable接口序列化一个对象并通过IO操作就可以保存在本地存储区中。而Parcelable的用法并不是如此。两者间虽然都支持序列化、反序列操作,但是其存储的媒介截然不同。前者一般是通过IO流写入本地硬盘文件中而Parcelable则在写入内存。运行在android手机上的应用追求运行速度更快。假设在同一进程的不同ActivityA和B之前传递一个对象,如果还需要先把A对象写入SD卡,然后B对象再从SD卡读到内存中,那么做了很多功夫。Adnroid提供Parcelable接口直接操作内存中的序列化对象,写入和读取速度明显大于IO操作,因此性能也有所提升。故Android实现序列化对象优先选择“Parcelable”。

如果涉及到网络传输保存数据的,一般还是推荐使用Serializable。

基于上述内容的认知,下面给出Android现实编程的例子:分别用两种序列化方式对具体对象进行序列化,并在不同的Activity中传递。

MainActiviy代码

package com.example.androidtest_parcelable;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

	private Button ac1,ac2;
	private Intent intent;
	private PersonByParcelable p;
	private PersonBySerializable s;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initListener();
		initData();
	}

	public void initView(){
		ac1 = (Button)findViewById(R.id.ac1);
		ac2 = (Button)findViewById(R.id.ac2);
	}

	public void initListener(){
		ac1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				intent = new Intent(MainActivity.this, ActivityA.class);
				Bundle b = new Bundle();
				b.putParcelable("parcelable", p);
				intent.putExtras(b);
				startActivity(intent);
			}
		});

		ac2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				intent = new Intent(MainActivity.this, ActivityB.class);
				Bundle b = new Bundle();
				b.putSerializable("serializable", s);
				intent.putExtras(b);
				startActivity(intent);
			}
		});
	}

	public void initData(){
		p = new PersonByParcelable();
		p.setName("parcelable");
		p.setAge(1);
		p.setAddress("我来自ParsonByParcelable");
		s = new PersonBySerializable();
		s.setName("serializable");
		s.setAge(2);
		s.setAddress("我来自PersonBySerializable");
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

ActivityA代码,用于显示反序列化Parcelable序列化的对象。

package com.example.androidtest_parcelable;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class ActivityA extends Activity{

	private TextView mTextView;
	private Intent intent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.ac1);
		initView();
	}

	public void initView(){
		intent = getIntent();
		Bundle b = intent.getExtras();
		PersonByParcelable p = (PersonByParcelable)b.getParcelable("parcelable");
		mTextView = (TextView)findViewById(R.id.mTextView);
		mTextView.setText("name:"+p.getName()+'\n'
				+"age:"+p.getAge()+"\n"
				+"address:"+p.getAddress());
	}
}

ActivityB代码,用于显示反序列化Serializable序列化的对象。

package com.example.androidtest_parcelable;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class ActivityB extends Activity{

	private TextView mTextView;
	private Intent intent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.ac2);
		initView();
	}

	public void initView(){
		intent = getIntent();
		Bundle b = intent.getExtras();
		PersonBySerializable s = (PersonBySerializable) b.getSerializable("serializable");
		mTextView = (TextView)findViewById(R.id.mTextView);
		mTextView.setText("name:"+s.getName()+'\n'
				+"age:"+s.getAge()+"\n"
				+"address:"+s.getAddress());
	}

}

分别对应的xml布局

MainActivity布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="welcome to yummlau's bolg"
        android:textSize="20sp" />

    <Button
        android:id="@+id/ac1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="传递Parcelable对象" />

    <Button
        android:id="@+id/ac2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="传递Serializable对象" />

</LinearLayout>

ActivitA和ActivityB布局(是相同的)

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_marginTop="10dp"
        android:id="@+id/mTextView"
        android:layout_width="fill_parent"
        android:layout_height="100dp"
        android:textSize="20sp"/>

</LinearLayout>

两个Bean类,分别用两种序列化手段

PersonByParcelable类,该类必须实现的的内容有:

1.无参构造器,用于产生类对象

2.有参构造器,用于反序列化后加载对象信息

3.writeToParcel(Parcel dest,int flags),此方法根据自己对象内容,分别按顺序写入dest包中,切记,这里与后面读取的顺序要一直。

4.describeContents(),此方法标志序列化内容,重写默认就可以了。

5.Parcelable.Creator<XXX>,此方法供系统内部存放序列化对象。

</pre></p><p><span style="font-family:SimHei;"></span><pre name="code" class="java" style="font-size:14px;">package com.example.androidtest_parcelable;

import android.os.Parcel;
import android.os.Parcelable;

public class PersonByParcelable implements Parcelable{

	private String name;
	private int age;
	private String address;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

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

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// TODO Auto-generated method stub
		dest.writeString(name);
		dest.writeInt(age);
		dest.writeString(address);

	}

	public static final Parcelable.Creator<PersonByParcelable> CREATOR = new Parcelable.Creator<PersonByParcelable>() {
        public PersonByParcelable createFromParcel(Parcel in) {
            return new PersonByParcelable(in);
        }  

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

    public PersonByParcelable(){

    }

    public PersonByParcelable(Parcel in){
    	this.name = in.readString();
    	this.age = in.readInt();
    	this.address = in.readString();
    }

}

PersonBySerializable类,该类必须实现的的内容有:

1.产生序列化ID

注意:该ID分为默认和随机,本demo因为有本地同个进程中实现并且序列化和反序列化都是用同个类,所以我取哪种方式都无所谓。然而如果是序列化和反序列分别在不同端的程序中,那么就应该保持ID的一致性才能正确反序列化对象。详情见开头的应用场景。

package com.example.androidtest_parcelable;

import java.io.Serializable;

public class PersonBySerializable implements Serializable{

	/**
	 * 序列化ID,自动生成
	 */
	private static final long serialVersionUID = 996340687144383140L;

	private String name;
	private int age;
	private String address;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}

}

Demo图示

运行后界面

分别点击“传递Parcelable对象”和“传递Serializable对象”

  

到此基本的传递对象演示完毕,如有错误欢迎指出。

时间: 2024-10-14 14:41:26

序列化手段(2)——Serializable和Parcelable的实现演示的相关文章

Android中Serializable和Parcelable序列化对象详解

学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Parcelable进行序列化操作 5.Parcelable的工作原理 6.相关实例 1.序列化的目的 (1).永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中 (2).通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的.因此序列化的目的是将对象数据转换成字节流的形式) (3).将对象数据在进程

Android中两种序列化方式的比较Serializable和Parcelable

Serializable和Parcelable接口可以完成对象的序列化过程,当我们需要通过Intent和Binder传输数据时就需要使用者两种序列化方式.还有,我们需要对象持久化到存储设备或者通过网络传输给其他客户端,这个使用也需要使用Serializale来完成对象的序列化.在Android应用开发中,这两种方式都很常见,但两者方式并不相同. 1.Serializable接口 Serializable接口是Java提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作.使用

Android 进阶6:两种序列化方式 Serializable 和 Parcelable

什么是序列化 我们总是说着或者听说着"序列化",它的定义是什么呢? 序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. 二进制序列化保持类型保真度,这对于在应用程序的不同调用之间保留对象的状态很有用.例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象.您可以将对象序列化到流.磁盘.内存和网络等等.远程处理使用序列化&

Android Serializable与Parcelable原理与区别

一.序列化.反序列化是什么? (1) 名词解释 对象的序列化 : 把Java对象转换为字节序列并存储至一个储存媒介的过程.对象的反序列化:把字节序列恢复为Java对象的过程. (2) 序列化详细解释 对象的序列化涉及三个点关键点:Java对象.字节序列.存储. 1. Java对象的组成?Java对象包含变量与方法.但是序列与反序列化仅处理Java变量而不处理方法,序列与反序列化仅对数据进行处理. 2. 什么是字符序列?字符序列是两个词,字符是在计算机和电信领域中,字符(Character)是一个

Serializable 和 parcelable的实现和比较

首先这个两个接口都是用来序列化对象的 但是两者在性能和应用场合上有区别,parcelable的性能更好,但是在需要保存或者网络传输的时候需要选择Serializable因为parcelable版本在不同版本可能不同 实现方面,serializable直接实现接口无需实现任何接口,只需要提供一个版本ID 而parcelable需要实现几个方法 // 写数据进行保存 public void writeToParcel(Parcel out, int flags) { out.writeInt(mDa

Intent传递对象——Serializable和Parcelable区别

前两篇文章讨论了Serializable和Parcelable实现Intent之间传递对象和对象数组的方式,两种方法实现上相似,效果一致,怎么选择用哪种方法实现呢? Intent在不同的组件中传递对象数据的应用非常普遍.下面介绍两种通过Intent传递对象的方法. 1.实现Serializable接口 2.实现Parcelable接口 为什么要将对象序列化? 1.永久性保存对象,保存对象的字节序列到本地文件中: 2.用过序列化对象在网络中传递对象: 3.通过序列化对象在进程间传递对象. 1.实现

Spark Task未序列化(Task not serializable)问题分析

问题描述及原因分析 在编写Spark程序中,由于在map等算子内部使用了外部定义的变量和函数,从而引发Task未序列化问题.然而,Spark算子在计算过程中使用外部变量在许多情形下确实在所难免,比如在filter算子根据外部指定的条件进行过滤,map根据相应的配置进行变换等.为了解决上述Task未序列化问题,这里对其进行了研究和总结. 出现"org.apache.spark.SparkException: Task not serializable"这个错误,一般是因为在map.fil

Intent传递对象——Serializable和Parcelable差别

前两篇文章讨论了Serializable和Parcelable实现Intent之间传递对象和对象数组的方式.两种方法实现上相似,效果一致,怎么选择用哪种方法实现呢? Intent在不同的组件中传递对象数据的应用很普遍.以下介绍两种通过Intent传递对象的方法. 1.实现Serializable接口 2.实现Parcelable接口 为什么要将对象序列化? 1.永久性保存对象,保存对象的字节序列到本地文件里. 2.用过序列化对象在网络中传递对象: 3.通过序列化对象在进程间传递对象. 1.实现S

Serializable和Parcelable的再次回忆

自己开发Android也有些时间了,Serializable和Parcelable遇到过不止一次了.但是每次别人问起具体的内容自己偏偏记得不是很清晰.因为某些原因再次梳理一下,以文章的形式给自己存储下来.温故而知新~!~! 序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中:另一方面,它们会以其他更容易理解的概念出现,例如加密.持久化.然而,序列化和反序列化的选型却是系统设计或重构一个重要的环节,在分布式.大数