android信息传递方式之bundle总结

Android bundle总结

1. Bundle简介

Bundle主要用于传递数据;它保存的数据,是以key-value(键值对)的形式存在的。

 

我们经常使用Bundle在Activity之间传递数据,传递的数据可以是boolean、byte、int、long、float、double、string等基本类型或它们对应的数组,也可以是对象或对象数组。当Bundle传递的是对象或对象数组时,必须实现Serializable 或Parcelable接口。下面分别介绍Activity之间如何传递基本类型、传递对象。

2. 传递基本类型

Bundle提供了各种常用类型的putXxx()/getXxx()方法,用于读写基本类型的数据。Bundle操作基本数据类型的API表格如下所示:

 

写数据的方法如下:

1. // "com.test" is the package name of the destination class  

2. // "com.test.Activity02" is the full class path of the destination class  

3. Intent intent = new Intent().setClassName("com.bundletest", "com.bundletest.Bundle02");  

4.   

5. Bundle bundle = new Bundle();  

6. bundle.putString("name", "skywang");  

7. bundle.putInt("height", 175);  

8. intent.putExtras(bundle);  

9.   

10. startActivity(intent);  

11.   

12. // end current class  

13. finish();  

对应的读数据的方法如下:

1. Bundle bundle = this.getIntent().getExtras();    

2.     

3. String name = bundle.getString("name");    

4. int height = bundle.getInt("height");  

3. 传递parcelable类型的对象

1) Parcelabel说明

Parcelable是Android自定义的一个接口,它包括了将数据写入Parcel和从Parcel中读出的API。一个实体(用类来表示),如果需要封装到bundle消息中去,可以通过实现Parcelable接口来实现。

Parcelable和Serializable的API如下表:

 

2) Parcelable接口说明

1. public interface Parcelable {  

2.     //内容描述接口,基本不用管  

3.     public int describeContents();  

4.     //写入接口函数,打包  

5.     public void writeToParcel(Parcel dest, int flags);  

6.     //读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数传入。  

7.     //为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例。  

8.     public interface Creator<T> {  

9.         public T createFromParcel(Parcel source);  

10.         public T[] newArray(int size);  

11.  }  

12. }  

实现Parcelable步骤

1implements Parcelable

2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据

3)重写describeContents方法,内容接口描述,默认返回0就可以

4)实例化静态内部对象CREATOR实现接口Parcelable.Creator

public static final Parcelable.Creator<T> CREATOR

注:其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方 法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。

简而言之:通过writeToParcel将 你的对象映射成Parcel对象,再通过createFromParcelParcel对象映射成你的对象。也可以将Parcel看成是一个流,通过 writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的 顺序必须一致。

3) Parcelable接口的实现方法

从parcelable接口定义中,我们可以看到,实现parcelable接口,需要我们实现下面几个方法:
(01)describeContents方法。内容接口描述,默认返回0就可以;
(02)writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.即打包需要传递的数据到Parcel容器保存,以便从parcel容器获取数据,该方法声明如下:
writeToParcel(Parcel dest, int flags) 具体参数含义见doc文档
(3.)静态的Parcelable.Creator接口,本接口有两个方法:
createFromParcel(Parcelin)  从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层。
newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(returnnew T[size])即可。方法是供外部类反序列化本类数组使用。

 

 

 

4) Parcelable demo

发送parcelable 实现的class 的方法:

·  // sent object through Pacelable  

·      private void sendParcelableDataThroughBundle(){    

·          Intent intent = new Intent().setClassName("com.bundletest", "com.bundletest.Bundle02");  

·    

·          Book mBook = new Book();  

·          mBook.setBookName("Android");  

·          mBook.setAuthor("skywang");  

·          mBook.setPublishTime(2013);  

·    

·          Bundle mBundle = new Bundle();  

·          mBundle.putParcelable("ParcelableValue", mBook);  

·          intent.putExtras(mBundle);  

·              

·          startActivity(intent);  

·          finish();  

·      }  

 

 

接收parcelable 实现的class 的方法:

·  private void receiveParcelableData() {  

·          Book mBook = (Book)getIntent().getParcelableExtra("ParcelableValue");  

·          if (mBook != null)  

·              Log.d(TAG, "receice parcel data -- " +  

·                         "Book name is: " + mBook.getBookName()+", "+  

·                         "Author is: " + mBook.getAuthor() + ", "+  

·                         "PublishTime is: " + mBook.getPublishTime());  

·      }  

 

Class实现parcelable接口的文件:

 

package com.bundletest;

 

import android.os.Parcel;  

import android.os.Parcelable;  

 

public class Book implements Parcelable {  

    private String bookName;  

    private String author;  

    private int publishTime;  

      

    public String getBookName() {  

        return bookName;  

    }  

    public void setBookName(String bookName) {  

        this.bookName = bookName;  

    }  

    public String getAuthor() {  

        return author;  

    }  

    public void setAuthor(String author) {  

        this.author = author;  

    }  

    public int getPublishTime() {  

        return publishTime;  

    }  

    public void setPublishTime(int publishTime) {  

        this.publishTime = publishTime;  

    }  

      

    public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {  

@Override

        public Book createFromParcel(Parcel source) {  

            Book mBook = new Book();  

            mBook.bookName = source.readString();  

            mBook.author = source.readString();  

            mBook.publishTime = source.readInt();  

            return mBook;  

        }  

@Override

        public Book[] newArray(int size) {  

            return new Book[size];  

        }  

    };  

      

@Override

    public int describeContents() {  

        return 0;  

    }  

 

@Override

    public void writeToParcel(Parcel parcel, int flags) {  

        parcel.writeString(bookName);  

        parcel.writeString(author);  

        parcel.writeInt(publishTime);  

    }  

}  

 

 

4. 传递Serializable类型的对象

1) Serializabel说明

Serializable是一个对象序列化的接口。一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。

2) Serializable接口的实现方法

很简单,只要implements Serializable接口就可以了

发送Serializable实现的class 的方法:

·  // sent object through seriable  

·      private void sendSeriableDataThroughBundle(){    

·          Intent intent = new Intent().setClassName("com.bundletest", "com.bundletest.Bundle02");  

·    

·          Person mPerson = new Person();  

·          mPerson.setName("skywang");  

·          mPerson.setAge(24);  

·    

·          Bundle mBundle = new Bundle();  

·          mBundle.putSerializable("SeriableValue",mPerson);  

·          intent.putExtras(mBundle);  

·              

·          startActivity(intent);  

·          finish();  

·      }  

接收Serializable实现的class 的方法:

·  private void receiveSeriableData() {  

·          Person mPerson = (Person)getIntent().getSerializableExtra("SeriableValue");    

·          if (mPerson != null)  

·              Log.d(TAG, "receice serial data -- " +  

·                         "The name is:" + mPerson.getName() + ", "+  

·                         "age is:" + mPerson.getAge());    

·      }  

 

Class实现Serializable接口的文件:

package com.bundletest;

 

import java.io.Serializable;  

 

public class Person implements Serializable {  

 

    private static final long serialVersionUID = 1L; 

 

    private String name;  

    private int age;  

    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;  

    }  

      

}  

 

5. Parcelable与Serializable比较

1) 作用

Serializable(是JavaSE本身就支持的)的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable

(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。

从上面的设计上我们就可以看出优劣了。

 

2) 效率及选择

Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

 

3) 编程实现

对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可。而 Parcelable则需要实现writeToParcel、describeContents函数以及静态的CREATOR变量,实际上就是将如何打包和解包的工作自己来定义,而序列化的这些操作完全由底层实现。

 

4) 高级功能上

Serializable序列化不保存静态变量,可以使用Transient关键字对部分字段不进行序列化,也可以覆盖writeObject、readObject方法以实现序列化过程自定义


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值