android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)

来源:互联网 发布:淘宝网旗袍专卖 编辑:程序博客网 时间:2024/04/28 13:04

转载+整理:
[android] Serializable 和 Parcelable 区别

android 中自定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable。

一 序列化原因:

1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象。 

二 至于选取哪种可参考下面的原则:

1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。


实现:
1 Serializable 的实现,只需要继承  implements Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化。

2 Parcelable:

Android 中Parcelable的作用


android提供了一种新的类型:Parcel。本类被用作封装数据的容器,封装后的数据可以通过Intent或IPC传递。 除了基本类型以

外,只有实现了Parcelable接口的类才能被放入Parcel中。

 

Parcelable实现要点:需要实现三个东西

1)writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.声明如下:

writeToParcel (Parcel dest, int flags) 具体参数含义见javadoc

2)describeContents方法。没搞懂有什么用,反正直接返回0也可以

3)静态的Parcelable.Creator接口,本接口有两个方法:

createFromParcel(Parcel in) 实现从in中创建出类的实例的功能

newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。估计本方法是供外部类反序列化本类数组使用。

实例:


这个接口的实例是通过Parcel进行存储的,在使用Parcelable的时候必须使用Parcelable.Creator。 

下面上代码:

首先修改main.xml,增加一个button

 

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <TextView    
  8. android:id="@+id/text"  
  9.     android:layout_width="fill_parent"   
  10.     android:layout_height="wrap_content"   
  11.     android:text="@string/hello"  
  12.     />  
  13. <Button  
  14. android:id="@+id/button"  
  15.     android:layout_width="wrap_content"   
  16.     android:layout_height="wrap_content"   
  17.     android:text="Parcelable">  
  18. </Button>  
  19. </LinearLayout>  


 

然后是主Activity ParcelableTest.java,这个类显示UI,并通过button点击事件启动另一个Activity -- ParcelableTest2,同时通过Parcelable接口传递一些数据。

 

[java] view plaincopyprint?
  1. package parcelable_test.com;  
  2.    
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.util.Log;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10.    
  11. public class ParcelableTest extends Activity implements OnClickListener{  
  12. public static final String KEY = "key";  
  13. private Button button;  
  14. public static final String TAG = "Parcelable";   
  15.    
  16. @Override  
  17. public void onCreate(Bundle savedInstanceState) {    
  18.         super.onCreate(savedInstanceState);    
  19.         setContentView(R.layout.main);  
  20.         init();  
  21.         Log.d(TAG, "ParcelableTest");  
  22.     }   
  23.    
  24. private void init(){  
  25. button = (Button)findViewById(R.id.button);  
  26. button.setOnClickListener(this);  
  27. }  
  28.    
  29. private void fun(){  
  30. Log.d(TAG, "fun");  
  31. Person mPerson = new Person();  
  32. mPerson.setName("tom");  
  33. mPerson.setAge(25);  
  34. Intent mIntent = new Intent(this,parcelable_test.com.ParcelableTest2.class);  
  35. Bundle mBundle = new Bundle();  
  36. mBundle.putParcelable(KEY, mPerson);  
  37. mIntent.putExtras(mBundle);  
  38. startActivity(mIntent);  
  39. }  
  40.    
  41. @Override  
  42. public void onClick(View v) {  
  43. switch (v.getId()) {  
  44. case R.id.button:  
  45. fun();  
  46. break;  
  47.    
  48. default:  
  49. break;  
  50. }  
  51. }  
  52. }  

  

 ParcelableTest2.java,这个类用于获取ParcelableTest传出的数据,并显示在UI上。

 

[java] view plaincopyprint?
  1. package parcelable_test.com;  
  2.    
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.util.Log;  
  6. import android.widget.TextView;  
  7.    
  8. public class ParcelableTest2 extends Activity{  
  9. private static final String TAG = ParcelableTest.TAG;  
  10. @Override  
  11. public void onCreate(Bundle savedInstanceState) {    
  12.         super.onCreate(savedInstanceState);    
  13.         setContentView(R.layout.main);       
  14.         Log.d(TAG, "ParcelableTest2");  
  15.         TextView textView = new TextView(this);  
  16.         Person mPerson = (Person)getIntent().getParcelableExtra(ParcelableTest.KEY);  
  17.         textView.setText("name = " + mPerson.getName() + "  age = " + mPerson.getAge());  
  18.         setContentView(textView);  
  19.     }   
  20. }  


下面就是最重要的类Person,Person类引用了Parcelable接口
[java] view plaincopyprint?
  1. package parcelable_test.com;  
  2. import android.os.Parcel;    
  3. import android.os.Parcelable;   
  4. import android.util.Log;  
  5. public class Person implements Parcelable{  
  6. private String name;  
  7. private int age;  
  8. private static final String TAG = ParcelableTest.TAG;   
  9. public String getName() {  
  10. return name;  
  11. }  
  12. public void setName(String name) {  
  13. this.name = name;  
  14. }  
  15. public int getAge() {  
  16. return age;  
  17. }  
  18. public void setAge(int age) {  
  19. this.age = age;  
  20. }  
  21. public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() {  
  22. @Override  
  23. public Person createFromParcel(Parcel source) {  
  24. Log.d(TAG,"createFromParcel");  
  25. Person mPerson = new Person();  
  26. mPerson.name = source.readString();  
  27. mPerson.age = source.readInt();  
  28. return mPerson;  
  29. }  
  30. @Override  
  31. public Person[] newArray(int size) {  
  32. // TODO Auto-generated method stub  
  33. return new Person[size];  
  34. }  
  35. };  
  36. @Override  
  37. public int describeContents() {  
  38. // TODO Auto-generated method stub  
  39. Log.d(TAG,"describeContents");  
  40. return 0;  
  41. }  
  42. @Override  
  43. public void writeToParcel(Parcel dest, int flags) {  
  44. // TODO Auto-generated method stub  
  45. Log.d(TAG,"writeToParcel");  
  46. dest.writeString(name);  
  47. dest.writeInt(age);  
  48. }  
  49. }  


最后在AndroidManifest.xml加入<activity android:name=".ParcelableTest2"></activity>
程序运行效果如下:
输出的log如下:
[plain] view plaincopyprint?
  1. 05-18 16:09:47.243 I/ActivityManager(   59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=parcelable_test.com/.ParcelableTest }  
  2. 05-18 16:09:47.383 D/Parcelable(  337): ParcelableTest  
  3. 05-18 16:09:48.003 I/ActivityManager(   59): Displayed activity parcelable_test.com/.ParcelableTest: 724 ms (total 724 ms)  
  4. 05-18 16:09:49.263 D/Parcelable(  337): fun  
  5. 05-18 16:09:49.263 D/Parcelable(  337): writeToParcel  
  6. 05-18 16:09:49.273 I/ActivityManager(   59): Starting activity: Intent { cmp=parcelable_test.com/.ParcelableTest2 (has extras) }  
  7. 05-18 16:09:49.453 D/Parcelable(  337): ParcelableTest2  
  8. 05-18 16:09:49.453 D/Parcelable(  337): createFromParcel  
  9. 05-18 16:09:49.952 I/ActivityManager(   59): Displayed activity parcelable_test.com/.ParcelableTest2: 562 ms (total 562 ms)  


通过log可知程序的运行情况,在mBundle.putParcelable(KEY, mPerson);时,调用了Person类中的public void writeToParcel(Parcel dest, int flags)方法,并向dest写数据,在 Person mPerson = (Person)getIntent().getParcelableExtra(ParcelableTest.KEY);的时候,调用了Person类中的public Person createFromParcel(Parcel source) 方法,创建了一个Person对象,并给这个对象的属性赋值,这里的Parcel source和Parcel dest,是相同的,然后返回这个Person对象。最后就可以打印出mPerson的属性信息了。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩不写作业怎么办呀 作业没写完的人怎么办? 孩子不写作业家长该怎么办 做作业做得慢怎么办 高一作业写得慢怎么办 孩子做作业不认真怎么办 孩子不主动做作业怎么办 写作业静不下心怎么办 小孩不写作业怎么办啊 小孩子写作业爱磨蹭怎么办 孩子在学校不写作业怎么办 鳗鱼刺卡在喉咙怎么办 被小鱼刺卡住了怎么办 喉咙上卡了鱼刺怎么办 跟团出去受伤了怎么办 平安易宝冻结了怎么办 车的保险到期没有交怎么办 人保外地险出险怎么办 婚姻经营不下去了怎么办 他不爱我,我该怎么办 没有我你怎么办钢琴版 没有你怎么办严爵歌词 没有羊毛戳针该怎么办 没有我你该怎么办歌词 雌激素低子宫内膜薄怎么办 没有我你怎么办的句子 没有我你怎么办百度云 何润东没有我你怎么办 想你了我该怎么办 没有你日子我该怎么办 没有我你怎么办mp3下载 如果没有你,我该怎么办 我该怎么办韩剧插曲 没有我你怎么办微盘 歌曲没有你我该怎么办 uc看小说收费了怎么办 发财树黄叶掉叶怎么办 5个月猫咪嘴巴臭怎么办 灿盛入伍柳岩怎么办 手机电用得快怎么办 身份证过期7个月怎么办