使用Intent傳遞對象
我們可以借助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傳遞對象