Android中如何使用Bundle传递对象[使用Serializable或者Parcelable]

Android中Bundle类的作用

Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。相对于Map,它提供了各种常用类型的putXxx()/getXxx()方法,如:putString()/getString()和putInt()/getInt(),putXxx()用于往Bundle对象放入数据,getXxx()方法用于从Bundle对象里获取数据。Bundle的内部实际上是使用了HashMap类型的变量来存放putXxx()方法放入的值。

用Bundle可以在Activity中传递基本数据类型,比如int、float、string等,但是现在的需求是如何在Activity中传递对象实例呢?就我目前所知的有两种,分别是java中Serializable和Android新引进的Parcelable方法。

 我们可以考虑采用Bundle.putSerializable(Key,Object);也可以考虑采用Bundle.putParcelable(Key, Object);其中前面一种方法中的Object必须要实现Serializable接口,后面一种方法中的Object必须要实现Parcelable接口。如果没有实现这两个接口之一,那么我们可以使用Bundle.putSerializable(Key,Object)或者Bundle.putParcelable(Key, Object),但起不到任何作用,下面我们以一个完整的例子来说明。

1.新建一个Android的工程,其中该工程的目录结构如下图:

2. 修改main.xml布局文件。布局文件的源码如下:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    > 
<TextView   
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    /> 
    <Button 
       android:id="@+id/serButton"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:text="Serializable"/> 
    <Button 
       android:id="@+id/parButton"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:text="Parcelable"/> 
</LinearLayout>

3.在工程的src目录下新建一个实体类包,命名为com.andy.entity.同时在该package中添加两个实体类,一个是Person.java,该类实现Serializable接口;一个是Police.java,该类实现Parcelable接口。代码分别如下:

Person.java:

package com.andy.entity; 
import java.io.Serializable; 
public class Person implements Serializable { 
    private static final long serialVersionUID = -6919461967497580385L; 
    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; 
    } 
}

Police.java:

package com.andy.entity; 
import android.os.Parcel; 
import android.os.Parcelable; 
public class Police implements Parcelable { 
    private String name; 
    private int workTime; 
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 
    public int getWorkTime() { 
        return workTime; 
    } 
    public void setWorkTime(int workTime) { 
        this.workTime = workTime; 
    } 
    public static final Parcelable.Creator<Police> CREATOR = new Creator<Police>() { 
        @Override 
        public Police createFromParcel(Parcel source) { 
            Police police = new Police(); 
            police.name = source.readString(); 
            police.workTime = source.readInt(); 
            return police; 
        } 
        @Override 
        public Police\[\] newArray(int size) { 
            return new Police\[size\]; 
        } 
    }; 
    @Override 
    public int describeContents() { 
        return 0; 
    } 
    @Override 
    public void writeToParcel(Parcel parcel, int flags) { 
        parcel.writeString(name); 
        parcel.writeInt(workTime); 
    } 
}

4.在包com.andy.testdemo中修改TestActivity.java类,同时在该包中添加类SerializableDemo和ParcelableDemo,分别继承了Activity类和分别显示Person对象和Police对象的数据。代码如下:

package com.andy.testdemo; 
import com.andy.entity.Person; 
import com.andy.entity.Police; 
import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
public class TestActivity extends Activity { 
    private Button sButton,pButton; 
    public final static String SER_KEY = "com.andy.ser"; 
    public final static String PAR_KEY = "com.andy.par"; 
    /** Called when the activity is first created. */
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        sButton = (Button)findViewById(R.id.serButton); 
        sButton.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View v) { 
                SerializeMethod(); 
            } 
        }); 
        pButton = (Button)findViewById(R.id.parButton); 
        pButton.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View v) { 
                PacelableMethod(); 
            } 
        }); 
    } 
    /** 
     * Serializeable传递对象的方法 
     */
    private void SerializeMethod(){ 
        Person mPerson = new Person();    
        mPerson.setName("andy");    
        mPerson.setAge(26);    
        Intent mIntent = new Intent(this,SerializableDemo.class);    
        Bundle mBundle = new Bundle();    
        mBundle.putSerializable(SER_KEY,mPerson);    
        mIntent.putExtras(mBundle);    
        startActivity(mIntent);    
    } 
    /** 
     * Pacelable传递对象方法  
     */
    private void PacelableMethod(){ 
        Police mPolice = new Police();    
        mPolice.setName("I am Police");       
        mPolice.setWorkTime(2008);    
        Intent mIntent = new Intent(this,ParcelableDemo.class);    
        Bundle mBundle = new Bundle();    
        mBundle.putParcelable(PAR_KEY, mPolice);    
        mIntent.putExtras(mBundle);    
        startActivity(mIntent);    
    } 
}

SerializableDemo.java类

package com.andy.testdemo; 
import com.andy.entity.Person; 
import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 
public class SerializableDemo extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        TextView mTextView = new TextView(this);    
        Person mPerson = (Person)getIntent().getSerializableExtra(TestActivity.SER_KEY);    
        mTextView.setText("You name is: " + mPerson.getName() + "/n"+    
                          "You age is: " + mPerson.getAge());    
        setContentView(mTextView);    
    } 
}

ParcelableDemo.java类:

package com.andy.testdemo; 
import com.andy.entity.Police; 
import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 
public class ParcelableDemo extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        TextView mTextView = new TextView(this);    
        Police mPolice = (Police)getIntent().getParcelableExtra(TestActivity.PAR_KEY);    
        mTextView.setText("Police name is: " + mPolice.getName()+"/n"+    
                          "WorkTime is: " + mPolice.getWorkTime() + "/n");    
        setContentView(mTextView);    
    } 
}

5.在AndroidManifest.xml文件中为新添加的两个Activity进行注册。

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.andy.testdemo"
      android:versionCode="1"
      android:versionName="1.0"> 
    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
        <activity android:name=".TestActivity"
                  android:label="@string/app_name"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
        <activity android:name=".SerializableDemo"/> 
        <activity android:name=".ParcelableDemo"/> 
    </application> 
    <uses-sdk android:minSdkVersion="8" /> 
</manifest>