Android序列化之Parcel
2015-09-16 22:52
344 查看
序列化方法
在Android系统中关于序列化的方法一般有两种,分别是实现Serializable接口和Parcelable接口,其中Serializable接口是来自Java中的序列化接口,而Parcelable是Android自带的序列化接口。上述的两种序列化接口都有各自不同的优缺点,我们在实际使用时需根据不同情况而定。
Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC,而相比之下Parcelable的性能更高(毕竟是Android自带的),所以当在使用内存时(如:序列化对象在网络中传递对象或序列化在进程间传递对象),更推荐使用Parcelable接口。
但Parcelable有个明显的缺点:不能使用在要将数据存储在磁盘上的情况(如:永久性保存对象,保存对象的字节序列到本地文件中),因为Parcel本质上为了更好的实现对象在IPC间传递,并不是一个通用的序列化机制,当改变任何Parcel中数据的底层实现都可能导致之前的数据不可读取,所以此时还是建议使用Serializable 。
实现Parcelable接口主要有以下几步:
1)implements Parcelable。
2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从Parcel容器获取数据。
3)重写describeContents方法,内容接口描述,默认返回0即可。
4)实例化静态内部对象CREATOR实现接口Parcelable.Creator 。
下面以一个例子说明:
MainActivity中启动OtherActivity,并将一个对象传过去,这个时候我们就需要对该类实现序列化
package com.test.parcel; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; public class StudentInfo implements Parcelable { public static final String TAG = "MyParcel"; private String name; private int age; private StudentInfo(){ } public StudentInfo(String name, int age){ Log.i(TAG, "StudentInfo construction"); this.name = name; this.age = age; } public String toString(){ return "name: " + name + ", age:" + age; } @Override public int describeContents() { // 默认返回0就可以了 Log.i(TAG, "describeContents()"); return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // 写数据的操作 dest.writeString(name); dest.writeInt(age); Log.i(TAG, "writeToParcel()"); } public static final Parcelable.Creator<StudentInfo> CREATOR = new Creator<StudentInfo>() { @Override public StudentInfo[] newArray(int size) { // TODO Auto-generated method stub return new StudentInfo[size]; } @Override public StudentInfo createFromParcel(Parcel source) { // 读数据,生成一个新对象,注意顺序跟写的顺序必须一致 StudentInfo stu = new StudentInfo(); stu.name = source.readString(); stu.age = source.readInt(); Log.i(TAG, "Parcelable.Creator createFromParcel()"); return stu; } }; }
我们在MainActivity中创建对象,通过Intent将该对象传给OtherActivity
package com.test.parcel; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends Activity implements View.OnClickListener{ private ArrayList<StudentInfo> list; private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(this); list = getData(); } private ArrayList<StudentInfo> getData() { ArrayList<StudentInfo> list = new ArrayList<StudentInfo>(); StudentInfo stu1 = new StudentInfo("scott", 23); StudentInfo stu2 = new StudentInfo("zhangsan", 18); StudentInfo stu3 = new StudentInfo("lishi", 20); list.add(stu1); list.add(stu2); list.add(stu3); return list; } @Override public void onClick 4000 (View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.btn: Intent intent = new Intent(this, OtherActivity.class); Log.i(StudentInfo.TAG, "intent putExtra()"); //若只想传一个对象,则直接调用putExtra(String name, Parcelable value)这个方法即可 //注意这里传的是List,但是该list容器的对象实现了序列化接口,下面这两种调用方法都可以 //intent.putExtra("students", list); intent.putParcelableArrayListExtra("students", list); startActivity(intent); break; default: break; } } }
另一个Activity读取数据,生产新对象
package com.test.parcel; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; public class OtherActivity extends Activity { private ArrayList<StudentInfo> list; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_other); list = getIntent().getParcelableArrayListExtra("students"); Iterator<StudentInfo> iter = list.iterator(); while(iter.hasNext()){ StudentInfo st = iter.next(); Log.i(StudentInfo.TAG, st.toString()); } } }
当执行putExtra()方法的时候,系统会自动调用Parcelable接口的writeToParcel()方法将数据写入内存中,这就是Android中的序列化。当程序执行 getIntent().getParcelableArrayListExtra(“students”)方法的时候,系统会调用CREATOR对象中的createFromParcel()方法,将序列化到内存的数据反序列化成对象。其实 createFromParcel(Parcel source) 方法的形参source和Parcelable中writeToParcel(Parcel dest, int flags)方法的形参dest是同一个对象。
运行的LOG信息如下:
I/MyParcel( 1268): StudentInfo construction I/MyParcel( 1268): StudentInfo construction I/MyParcel( 1268): StudentInfo construction I/MyParcel( 1268): intent putExtra() I/MyParcel( 1268): writeToParcel() I/MyParcel( 1268): writeToParcel() I/MyParcel( 1268): writeToParcel() I/MyParcel( 1268): Parcelable.Creator createFromParcel() I/MyParcel( 1268): Parcelable.Creator createFromParcel() I/MyParcel( 1268): Parcelable.Creator createFromParcel() I/MyParcel( 1268): name: scott, age:23 I/MyParcel( 1268): name: zhangsan, age:18 I/MyParcel( 1268): name: lishi, age:20
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories