1. 程式人生 > >使用Intent傳遞對象

使用Intent傳遞對象

eat content 意思 strong 無法 tag bsp 存儲 png

我們可以借助Intent來啟動活動,發送廣播,啟動服務等。

還可以通過putExtra()方法傳遞一些數據。

但我們會發現putExtra()方法中所支持的類型是有限的。當我們想去傳遞一些自定義對象的時候,會發現無法通過putExtra()的方法進行傳遞。

但Intent是可以傳遞對象的。

使用Intent傳遞對象的通常有兩種方式 Serializable Parcelable

Serializable方式

Serializable是序列化的意思,表示將一個對象轉換成可存儲或可傳輸的狀態。序列化後的對象可以在網絡上進行傳輸,也可以存儲到本地。

序列化的方法: 只需要讓一個類去實現Serializable這個接口就可以了。

創建一個SerializableTest項目,並增加兩個Activity,一個名為FristActivity,一個名為SecondActivity。

新建一個Person類並實現Serializable接口,代碼如下
 1 public class Person implements Serializable{
 2     private String name;
 3 
 4     public String getName() {
 5         return name;
 6     }
 7 
 8     public void setName(String name) {
9 this.name = name; 10 } 11 }

這裏僅有一個name字段。

修改FirstActivity中的代碼
 1 public class FirstActivity extends AppCompatActivity {
 2 
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_first);
7 Person person = new Person(); 8 person.setName("張三"); 9 Intent intent = new Intent(FirstActivity.this,SecondActivity.class); 10 intent.putExtra("person_data",person); 11 startActivity(intent); 12 } 13 }

實現序列化後,Person對象可以像其他數據一樣通過putExtra()方法傳輸。

修改SecondActivity中的代碼
 1 public class FirstActivity extends AppCompatActivity {
 2 
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_first);
 7         Person person = new Person();
 8         person.setName("張三");
 9         Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
10         intent.putExtra("person_data",person);
11         startActivity(intent);
12     }
13 }

這裏調用了getSerializableExtra()方法來獲取參數傳遞過來的序列化對象。

運行程序,發現已經成功傳遞打印出來。

技術分享


Parcelable方式

Parcelable方式的實現原理是將一個完整的對象進行分解,而分解後的每一部分都是Intent所支持的數據類型。這樣也就實現傳遞對象的功能了。

修改Person類中的代碼
 1 public class Person implements Parcelable{
 2     private String name;
 3 
 4     public String getName() {
 5         return name;
 6     }
 7 
 8     public void setName(String name) {
 9         this.name = name;
10     }
11 
12     @Override
13     public int describeContents() {
14         return 0;
15     }
16 
17     @Override
18     public void writeToParcel(Parcel dest, int flags) {
19         dest.writeString(name); //寫出name
20     }
21 
22     public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>(){
23         @Override
24         public Person createFromParcel(Parcel source) {
25             Person person = new Person();
26             person.name = source.readString();
27             return person;
28         }
29 
30         @Override
31         public Person[] newArray(int size) {
32             return new Person[size];
33         }
34     };
35 }

這裏首先讓Person類實現了Parcelable接口。

實現Parcelable接口後就必須重寫describeContents()和writeToParcel()這兩個方法。

其中describeContents()方法直接返回0就可以了。

而writeToParcel()方法中需要調用Parcel的writeXXX()方法。將Person類中的字段寫出。

寫出字符串型數據就要調用writeString()方法。依次類推。

除此之外還必須在Person類中提供一個名為CREATOR的常量。

這裏創建了一個Parcelable.Creator接口的一個實現,並將泛型指定為Person。

接著需要重寫createFromParcel()和new Array()這兩個方法。

在createFromParcel()方法中我們要去讀取剛才寫出的name字段,並創建一個Person對象返回。

其中name字段都是通過readXXX()方法讀取到的。

註意這裏讀取的順序一定要和剛才寫出的順序完全一致。

而newArray()方法中只需要new出一個Person數組,並使用方法中傳入的size作為數組大小就可以了。

修改SecondActivity中的代碼
 1 public class SecondActivity extends AppCompatActivity {
 2 
 3     private static final String TAG = "SecondActivity";
 4 
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_second);
 9         Person person = (Person)getIntent().getParcelableExtra("person_data");
10         Log.d(TAG, "Name:" + person.getName());
11     }
12 }

這裏不是再調用getSerializableExtra()方法,而是調用getParcelableExtra()方法。

其他的地方完全一致。


Serializable的方式較為簡單,但由於會將整個對象進行序列化,因此效率會比Parcelable方式低一些,所以在通常情況下還是更加推薦使用Parcelable的方式來實現Intent傳遞對象的功能。

使用Intent傳遞對象